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

            Bug ID: 128312
           Summary: Return slot optimization makes a throwing call's
                    partial result visible in the caller's catch handler
           Product: gcc
           Version: 12.5.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lzy20000419 at outlook dot com
  Target Milestone: ---

```c++
struct S { int a[8]; };

__attribute__((noipa)) S
f (int t)
{
  S r;
  for (int i = 0; i < 8; i++)
    r.a[i] = 42;
  if (t)
    throw 1;
  return r;
}

__attribute__((noipa)) int
g (int t)
{
  S d;
  for (int i = 0; i < 8; i++)
    d.a[i] = 0;
  try
    {
      d = f (t);
    }
  catch (int)
    {
      return d.a[0];
    }
  return -1;
}

int
main ()
{
  if (g (1) != 0)
    __builtin_abort ();
}
```

$ g++ -O1 t.C && ./a.out
Aborted

Expected: no abort. `d = f (t)` is an assignment, so when f throws, d must keep
its old value 0. At -O1/-O2/-O3/-Os g (1) returns 42. -O0 and clang++ -O2 are
fine; -fsanitize=address,undefined is clean.

It fails with 6.3 through 16.1 and trunk.

https://godbolt.org/z/vccznqYK3 (left gcc 6.3, right trunk)

Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.

Reply via email to