From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id C93BC3858027; Mon, 7 Nov 2022 13:34:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C93BC3858027 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667828090; bh=f/pC9gst/DhL9i/j76cr4JU1iqF8a9wQzNVxgMQmmC0=; h=From:To:Subject:Date:From; b=IzRuqrBbp4RRfT4yw3cctxyHliW+96q+z4TlexLmztEiVKyusBT21ipAt6mI/SCaR 6Sk5fT86lOxzEn8i9iN6NKyAFb1tqf0Vc7vpNwCmM7tO+qjOE1/La8A1IahRLjh0Ey UCKdpCvJS7cI36dD45TrhdOVB5eKDN9qSg0ofUg4= From: "boris at kolpackov dot net" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/107555] New: Never constructed object destroyed during exception handling Date: Mon, 07 Nov 2022 13:34:49 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 12.2.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: boris at kolpackov dot net X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D107555 Bug ID: 107555 Summary: Never constructed object destroyed during exception handling Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: boris at kolpackov dot net Target Milestone: --- I have a fairly complex function (nested loops, try-catch blocks, etc) that= on throwing an exceptions tries to destroy a stack object (suspected to be the return value) that was never constructed. This feels like a mis-compilation introduced in GCC 12 because: 1. The issue disappears if optimization is enabled. 2. The issue disappears if I get rid of the return value with otherwise min= imal changes. 3. Does not reproduce with GCC 11 or 10 in otherwise the same build. I am not sure what's the best way to debug this. Coming up with a minimal reproduce feels hopeless. But I can easily provide the instructions on how = to reproduce this on the actual source code. In the meantime, I will capture s= ome background below: The relevant fragment of the stack trace looks like this: #18 0x00007f7472e5d270 in std::pair::~pair (this=3D0x7ffdbe099e30, __in_chrg=3D) at /usr/include/c++/12/bits/stl_pair.h:185 #19 0x00007f7472e4ab19 in build2::cc::compile_rule::extract_headers (....) = at .../compile-rule.cxx:4768 The pair object being destroyed at frame #18 was never constructed and eventually leads to "free(): invalid pointer" and abort. The extract_header= s() function has the following overall structure (only what I believe are the relevant parts are shown): pair compile_rule:: extract_headers (....) { ... if (something) return make_pair (file_cache::entry (), false); // <-- one of early ret= urns ... try { ... if (something) throw failed (); // <-- the exception that is thrown } // <-- line 4768 catch (const process_error& e) { ... throw failed (); } ... return make_pair (move (psrc), puse);=20 } As can be seen, the function has a bunch of early returns. Other than the returns, it does not construct any pair instances. The call site look like this: pair psrc (file_cache::entry (), false); if (something) { ... psrc =3D extract_headers (....);=20 } Note that I checked and the `this` pointer from frame #18 does not point to psrc form the call site. I was able to work around this issue by getting rid of the return type and instead passing the result object by reference: void compile_rule:: extract_headers (...., pair& result) { ... if (something) return; ... result.first =3D move (psrc); result.second =3D puse; } And the call site: pair psrc (file_cache::entry (), false); if (something) { ... extract_headers (...., psrc);=20=20 }=