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.