Description of problem: GCL misbehaves when built with gcc 12, including strange segfaults. Upstream produced a test case, which I have reduced to this: #include <stdio.h> int main(int argc,char * argv[]) { long x; if (argc != 2) { fprintf(stderr, "Usage: %s integer\n", argv[0]); return 3; } sscanf(argv[1],"%ld",&x); long fx = ((unsigned long)&x >= 0x8000000000000000) ? (long)((long)&x - 0xA000000000000000) : x; if (fx < 0) { if (((0x2000000000000000 - fx) & 0xC000000000000000) == 0) return 1; else return 0; } else { return 2; } } The test is to invoke this program with argument -8874444426961747968. When built with gcc 11, the test passes (exits with 0) at all optimization levels. When built with gcc 12 at optimization levels -O0 or -O1, the test passes. When built with -O2 it fails (exits with 1). When built with -O2 -fno-tree-vrp, the test passes. Changing the code in the "then" branch of "if (fx < 0)" to this: return (((0x2000000000000000 - fx) & 0xC000000000000000) == 0) ? 1 : 0; results in a passing test. Version-Release number of selected component (if applicable): gcc-12.2.1-4.fc38.x86_64 How reproducible: Always Steps to Reproduce: 1. Say the code above is in a file named t.c. Run "gcc -O2 -o t t.c" 2. Run "./t -8874444426961747968" 3. "echo $?" shows exit code 1 4. Run "gcc -O2 -fno-tree-vrp -o t t.c" 5. Run "./t -8874444426961747968" 6. "echo $?" shows exit code 0 Actual results: An unexpected branch is taken when -ftree-vrp is in effect. Expected results: Additional info:
That testcase invokes undefined behavior. Compile/link it with -fsanitize=undefined and you'll see it: /tmp/1.c:18:32: runtime error: signed integer overflow: 2305843009213693952 - -8874444426961747968 cannot be represented in type 'long int' Signed integer overflow is UB in C/C++.
Ah, right you are. Thank you, Jakub. I will pass that information upstream.