public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "boris at kolpackov dot net" <gcc-bugzilla@gcc.gnu.org>
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	[thread overview]
Message-ID: <bug-107555-4@http.gcc.gnu.org/bugzilla/> (raw)

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107555

            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 minimal
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 some
background below:

The relevant fragment of the stack trace looks like this:

#18 0x00007f7472e5d270 in std::pair<build2::file_cache::entry, bool>::~pair
(this=0x7ffdbe099e30, __in_chrg=<optimized out>) 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_headers()
function has the following overall structure (only what I believe are the
relevant parts are shown):

pair<file_cache::entry, bool> compile_rule::
extract_headers (....)
{

  ...

  if (something)
   return make_pair (file_cache::entry (), false);  // <-- one of early returns

  ...


  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); 
}

As can be seen, the function has a bunch of early returns. Other than the
returns, it does not construct any pair<file_cache::entry, bool> instances.

The call site look like this:

pair<file_cache::entry, bool> psrc (file_cache::entry (), false);

if (something)
{
  ...
  psrc = extract_headers (....); 
}

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<file_cache::entry, bool>& result)
{
    ...

  if (something)
   return;

  ...

  result.first = move (psrc);
  result.second = puse;
}

And the call site:

pair<file_cache::entry, bool> psrc (file_cache::entry (), false);
if (something)
{
  ...
  extract_headers (...., psrc);  
}

             reply	other threads:[~2022-11-07 13:34 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-07 13:34 boris at kolpackov dot net [this message]
2022-11-08  9:28 ` [Bug c++/107555] " rguenth at gcc dot gnu.org
2022-11-08  9:47 ` boris at kolpackov dot net
2022-11-08 10:47 ` redi at gcc dot gnu.org
2022-11-08 13:12 ` boris at kolpackov dot net
2022-11-08 13:12 ` boris at kolpackov dot net
2022-11-08 13:21 ` boris at kolpackov dot net
2022-11-08 16:59 ` pinskia at gcc dot gnu.org
2022-11-08 17:07 ` redi at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-107555-4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).