https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87311
Bug ID: 87311 Summary: missing integer overflow detection on negation of the minimum value with -ftrapv or UB sanitizer Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: vincent-gcc at vinc17 dot net Target Milestone: --- When using -ftrapv or -fsanitize=undefined, GCC sometimes misses integer overflow detection on negation of the minimum value (e.g. LONG_MIN for type long). For instance: #include <stdio.h> #include <limits.h> int main (void) { long i, j; i = j = LONG_MIN; i = -i - 1; fprintf (stderr, "%ld\n", i); j = -j; fprintf (stderr, "%ld\n", j); return 0; } $ gcc-snapshot tst.c -o tst -ftrapv $ ./tst 9223372036854775807 zsh: abort (core dumped) ./tst Integer overflow on -j is detected, but not the one on -i. With optimizations, none is detected: $ gcc-snapshot tst.c -o tst -ftrapv -O $ ./tst 9223372036854775807 -9223372036854775808 which is particularly bad because the code may assume that negating a negative value yields a positive value. With -fsanitize=undefined, one gets the expected error "runtime error: negation of -9223372036854775808 cannot be represented in type 'long int'; cast to an unsigned type to negate this value to itself" only for -j (with or without optimizations). All GCC versions seem to be affected, including the trunk.