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.

Reply via email to