https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112301
Bug ID: 112301 Summary: Double destruction of returned object when exiting the scope causes an exception which gets rethrown Product: gcc Version: 12.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: alexander.gr...@tu-dresden.de Target Milestone: --- Created attachment 56476 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=56476&action=edit More complete example with logging pointers I debugged a heap corruption I traced back to a use-after-free caused by an extra destructor call. I suspect the cause could be the fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33799 where a throwing destructor led to a missing destructor call. It could be similar to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12751 which also had an extra destructor call generated for an already destructed instance. Minimized code sample: #include <stdexcept> #include <cassert> int num = 0; struct ptr{ ptr(){ ++num; } ptr(ptr&&){ ++num; } ~ptr(){ assert(num-- > 0); } }; struct ThrowOnExit{ ~ThrowOnExit() noexcept(false){ throw std::runtime_error(""); } }; ptr foo(ptr x){ try{ ThrowOnExit _; return x; }catch (const std::exception&) { throw; } } void wrapper(){ try{ foo(ptr{}); }catch(const std::exception&){} } int main(){ wrapper(); } The assertion fails, although it should not. Logging the constructions and destructions and removing the assert gives me this: construct 0x7ffd4538088e move construct 0x7ffd4538088f free 0x7ffd4538088f free 0x7ffd4538088f free 0x7ffd4538088e