[Bug c/87311] New: missing integer overflow detection on negation of the minimum value with -ftrapv or UB sanitizer
vincent-gcc at vinc17 dot net
gcc-bugzilla@gcc.gnu.org
Fri Sep 14 20:01:00 GMT 2018
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.
More information about the Gcc-bugs
mailing list