https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81900
Bug ID: 81900 Summary: GCC trunk miscompiles Perl / __sigsetjmp issue Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pipcet at gmail dot com Target Milestone: --- Created attachment 42007 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42007&action=edit creduce-minimized test case Hi, I'm having trouble running a GCC/trunk-compiled Perl; I first noticed the problem on my WebAssembly port, but I think I can reproduce it on x86_64 built from the standard GCC tree. I also think this is a GCC bug. After some editing, I've managed to generate a (somewhat) minimized testcase: Perl_croak() __attribute__((noreturn)); *Perl_sv_gets(); a() { __sigsetjmp(); char *b; if ((b = Perl_sv_gets()) == 0) Perl_croak("No Perl script found in input\n"); if (*b == '#') __asm__("" : : ""("badbad")); } The intended behaviour is that Perl_sv_gets() can return a NULL pointer, in which case the pointer isn't dereferenced and Perl_croak() is called instead. However, the assembly output I get is: xorl %eax, %eax call __sigsetjmp xorl %eax, %eax call Perl_sv_gets cmpb $35, (%rax) The call to Perl_croak has been removed, and the return value of Perl_sv_gets() is unconditionally dereferenced. That's wrong, right? I'm compiling with: $ ~/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/xgcc -B /home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/ -v -S -DPERL_CORE -fwrapv -std=c89 -O3 -fno-strict-aliasing -w -Wfatal-errors testcase.i -o tmp.s || exit 1 Reading specs from /home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/specs COLLECT_GCC=/home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/xgcc Target: x86_64-pc-linux-gnu Configured with: ./configure --target=x86_64-pc-linux-gnu --disable-bootstrap --enable-languages=c Thread model: posix gcc version 8.0.0 20170819 (experimental) (GCC) COLLECT_GCC_OPTIONS='-B' '/home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/' '-v' '-S' '-D' 'PERL_CORE' '-fwrapv' '-std=c90' '-O3' '-fno-strict-aliasing' '-w' '-Wfatal-errors' '-o' 'tmp.s' '-mtune=generic' '-march=x86-64' /home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/cc1 -fpreprocessed testcase.i -quiet -dumpbase testcase.i -mtune=generic -march=x86-64 -auxbase-strip tmp.s -O3 -Wfatal-errors -w -std=c90 -version -fwrapv -fno-strict-aliasing -o tmp.s GNU C89 (GCC) version 8.0.0 20170819 (experimental) (x86_64-pc-linux-gnu) compiled by GNU C version 6.4.0 20170724, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version none GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 GNU C89 (GCC) version 8.0.0 20170819 (experimental) (x86_64-pc-linux-gnu) compiled by GNU C version 6.4.0 20170724, GMP version 6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version none GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: d531daafd687d9500452e3b103d32887 COMPILER_PATH=/home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/ LIBRARY_PATH=/home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/:/lib/x86_64-linux-gnu/:/lib/../lib64/:/usr/lib/x86_64-linux-gnu/:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-B' '/home/pip/git/asmjs/subrepos/gcc/host-x86_64-pc-linux-gnu/gcc/' '-v' '-S' '-D' 'PERL_CORE' '-fwrapv' '-std=c90' '-O3' '-fno-strict-aliasing' '-w' '-Wfatal-errors' '-o' 'tmp.s' '-mtune=generic' '-march=x86-64' The call to sigsetjmp appears to be necessary to trigger the bug. Sorry if this is a duplicate or a known issue; right now, I don't have the time to investigate further. The call appears to be eliminated in a tree optimization pass, so I'm tentatively choosing that component.