https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128148
Bug ID: 128148
Summary: wrong code at -O2 with -fnon-call-exceptions: store to
a global moved after a load that throws
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: wrong-code
Severity: normal
Priority: P3
Component: rtl-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 <sys/mman.h>
long g;
static void handler(int) { throw 0; }
__attribute__((noinline)) int f(int *p, long b)
{
g = b;
return *p;
}
int main()
{
int *p = (int *)mmap(0, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
signal(SIGSEGV, handler);
try {
return f(p, 1);
} catch (int) {
__builtin_printf("%ld\n", g);
}
}
godbolt: https://godbolt.org/z/7jhWcfEYx
*p is on a PROT_NONE page, so the load faults and the SIGSEGV handler throws
(as in g++.dg/eh/sighandle.C); g = b comes before the load, so the catch in
main must print 1. With -fnon-call-exceptions and -O0, -O1 or -O2
-fno-schedule-insns2 the program prints 1; with -O2, -O3 or -Os (also -O2
-fschedule-insns -fno-schedule-insns2) it prints 0.