https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128639
Bug ID: 128639
Summary: [14/15/16/17 Regression] wrong code at -O2: tail
recursion moves a trapping division above the
recursive call since r8-1042
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: jeffchen006 at gmail dot com
Target Milestone: ---
#include <cstdio>
int z;
int f(int n, int d) {
if (!n)
return d ? 0 : throw 0;
int r = f(n - 1, d);
return r + 2 / d;
}
int main() {
try { printf("%d\n", f(1, z)); } catch (int) { printf("caught\n"); }
}
$ g++ -O0 t.cpp && ./a.out
caught
$ g++ -O2 t.cpp && ./a.out
(no output, SIGFPE, exit 136)
Expected: caught. f(1, 0) calls f(0, 0), which throws before 2 / d runs. -O2
does the division first and gets SIGFPE.
Suspected cause: tree-tailcall: a trapping statement after the recursive call
is moved above it when the function becomes a loop (first bad 48932682a54,
2017, PR66313).
Avoided by: -fno-optimize-sibling-calls.
Known to fail: 8.5.0, 10.5.0, 11.4.0, 12.5.0, 13.4.0, 14.3.0, 15.2.0, 16.2.0,
17.0.
Known to work: 7.5.0.
-O0 -fsanitize=undefined,address is clean.
gcc version 17.0.0 20261111 (experimental) (a2a11abfad3), x86_64-pc-linux-gnu
Configured with: --enable-languages=c,c++ --disable-multilib
--disable-bootstrap --enable-checking=release