Fix make_shared with throwing destructors #1736
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #1733.
The STL is allowed to assume that user destructors don't emit exceptions (WG21-N4878 [tab:cpp17.destructible]), but user destructors can be marked
noexcept(false)as long as they never emit exceptions when interacting with the STL. The bug being fixed here is that 9 out of 10shared_ptrcontrol blocks would fail to compile fornoexcept(false)destructors. (The only unaffected control block was the simplest,_Ref_count, which stores only a pointer.)We can mark
~_Ref_count_resource()and~_Ref_count_resource_alloc()asnoexceptand define them as= default;thanks to WG21-N4878 [dcl.fct.def.default]/2.2:For the other destructors which were already being provided by the library, the fix is to mark them as
noexcept. I'm additionally marking them asvirtual overridefor consistency, and copying the// TRANSITION, should be non-virtualcomment from the base class.Because this interacts with virtual member functions, we need to think carefully about ABI. I manually verified that the vtable layout isn't changing;
Before:
After:
The virtual function table order is unchanged, and it follows the base class order (which, after thinking about it for a moment, is how virtual functions must work):
STL/stl/inc/memory
Lines 1046 to 1121 in c5ee3b3
The only difference is that
/d1reportSingleClassLayoutis reporting "thisadjustors" in derived order, and I'm inserting the definitions of~_Ref_count_resource()and~_Ref_count_resource_alloc()near the top. As far as I know, this difference is purely cosmetic (it doesn't reflect any physical ordering).The test contains comments indicating which control blocks are being tested; mostly for clarity, partially so that any future searches for control block names will find these tests.
Along the way, I reported (internally, because I was a lazy kitty) and worked around: