https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128147
Bug ID: 128147
Summary: wrong code at -O1 and above with -fnon-call-exceptions
-fno-delete-dead-exceptions: trapping load skipped
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: kyuwoncho18 at gmail dot com
Target Milestone: ---
Target: x86_64-pc-linux-gnu
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
static void on_segv(int) { throw 1; }
__attribute__((noinline)) int f(int *p, int c)
{
int x = *p;
if (c)
return x;
return 0;
}
int main()
{
int *p = (int *)mmap(0, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED || signal(SIGSEGV, on_segv) == SIG_ERR)
return 2;
try { printf("returned %d\n", f(p, 0)); }
catch (int) { puts("caught"); }
}
godbolt: https://godbolt.org/z/f8eEWb3v3
On x86_64-linux-gnu, compile this C++ program with -x c++ -lstdc++
-fnon-call-exceptions -fno-delete-dead-exceptions. The load from the PROT_NONE
mapping must fault and the SIGSEGV handler must throw, so the correct output is
caught. With -O0 or -O2 -fno-tree-sink the program prints caught; with -O1,
-O2, -O3 or -Os it prints returned 0.