http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52478
Bug #: 52478 Summary: -ftrapv calls the wrong functions in libgcc Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: bur...@gcc.gnu.org As PR 19020 has been closed ("let's ditch antiquated stuff and start afresh") - open a fresh bug. Using -ftrapv works with i368-gnu-linux: $ gcc -m32 -ftrapv hjfff.c && ./a.out Aborted (core dumped) $ But not on x86-64-gnu-linux: $ gcc -m64 -ftrapv hjfff.c && ./a.out $ In the debugger, one sees: a) i386: __addvsi3 (a=2147483647, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:79 (gdb) pt a type = int b) x86-64: (gdb) __addvdi3 (a=2147483647, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82 (gdb) pt a type = long int Thus, there is no overflow in that function. THUS: On i386 it calls the correct function but on x86-64 it should call the SI not the DI function. * * * For long/LONG_MAX, one has again: a) -m32 __addvsi3 (a=2147483647, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:79 79 { (gdb) pt a type = int b) -m64 __addvdi3 (a=9223372036854775807, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82 82 if (b >= 0 ? w < a : w > a) (gdb) pt a type = long int THUS: x86-64 calls correctly the DI function but i386 wrongly the SI function * * * long long / LLONG_MAX: a) -m32: __addvdi3 (a=9223372036854775807, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82 82 if (b >= 0 ? w < a : w > a) (gdb) pt a type = long int b) -m64 __addvdi3 (a=9223372036854775807, b=1) at /home/tob/projects/gcc-trunk-checkout/libgcc/libgcc2.c:82 82 if (b >= 0 ? w < a : w > a) (gdb) pt a type = long int THUS: Both x86-64 and i386 call the "long int" instead of the "long long" function. I had exepected a TI version, which does not seem to exist. * * * #include <limits.h> int __attribute__((noinline)) iaddv (int a, int b) { return a + b; } int main(void) { return iaddv (INT_MAX, 1); }