diff options
author | Marek Polacek <polacek@redhat.com> | 2017-09-04 11:30:26 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2017-09-04 11:30:26 +0000 |
commit | 8d2b48ae9f3e1e70dfe2aaf32abb9e74594b8875 (patch) | |
tree | 9b9eb5195184349428955b9bc16261b81fef83bb | |
parent | e910a9b11a04d37e2a9a92dd2bc39097728f132c (diff) | |
download | gcc-8d2b48ae9f3e1e70dfe2aaf32abb9e74594b8875.zip gcc-8d2b48ae9f3e1e70dfe2aaf32abb9e74594b8875.tar.gz gcc-8d2b48ae9f3e1e70dfe2aaf32abb9e74594b8875.tar.bz2 |
re PR sanitizer/82072 (sanitizer does not detect an overflow from LLONG_MIN)
PR sanitizer/82072
* convert.c (do_narrow): When sanitizing signed integer overflows,
bail out for signed types.
(convert_to_integer_1) <case NEGATE_EXPR>: Likewise.
* c-c++-common/ubsan/pr82072.c: New test.
From-SVN: r251651
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/convert.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/pr82072.c | 19 |
4 files changed, 44 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 85eab15..0bc8b4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-09-04 Marek Polacek <polacek@redhat.com> + + PR sanitizer/82072 + * convert.c (do_narrow): When sanitizing signed integer overflows, + bail out for signed types. + (convert_to_integer_1) <case NEGATE_EXPR>: Likewise. + 2017-09-04 Richard Biener <rguenther@suse.de> PR tree-optimization/82060 diff --git a/gcc/convert.c b/gcc/convert.c index 22152ca..139d790 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -434,6 +434,13 @@ do_narrow (location_t loc, typex = lang_hooks.types.type_for_size (TYPE_PRECISION (typex), TYPE_UNSIGNED (typex)); + /* The type demotion below might cause doing unsigned arithmetic + instead of signed, and thus hide overflow bugs. */ + if ((ex_form == PLUS_EXPR || ex_form == MINUS_EXPR) + && !TYPE_UNSIGNED (typex) + && sanitize_flags_p (SANITIZE_SI_OVERFLOW)) + return NULL_TREE; + /* But now perhaps TYPEX is as wide as INPREC. In that case, do nothing special here. (Otherwise would recurse infinitely in convert. */ @@ -895,7 +902,12 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) TYPE_UNSIGNED (typex)); if (!TYPE_UNSIGNED (typex)) - typex = unsigned_type_for (typex); + { + /* Using unsigned arithmetic may hide overflow bugs. */ + if (sanitize_flags_p (SANITIZE_SI_OVERFLOW)) + break; + typex = unsigned_type_for (typex); + } return convert (type, fold_build1 (ex_form, typex, convert (typex, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 83f05b7..45cee1f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-09-04 Marek Polacek <polacek@redhat.com> + + PR sanitizer/82072 + * c-c++-common/ubsan/pr82072.c: New test. + 2017-09-04 Richard Biener <rguenther@suse.de> PR tree-optimization/82060 diff --git a/gcc/testsuite/c-c++-common/ubsan/pr82072.c b/gcc/testsuite/c-c++-common/ubsan/pr82072.c new file mode 100644 index 0000000..d568340 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/pr82072.c @@ -0,0 +1,19 @@ +/* PR sanitizer/82072 */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=signed-integer-overflow" } */ + +int +main () +{ + long long l = -__LONG_LONG_MAX__ - 1; + int i = 0; + asm volatile ("" : "+r" (i)); + i -= l; + asm volatile ("" : "+r" (i)); + i = -l; + asm volatile ("" : "+r" (i)); + return 0; +} + +/* { dg-output "signed integer overflow: 0 - -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*negation of -9223372036854775808 cannot be represented in type 'long long int'\[^\n\r]*; cast to an unsigned type to negate this value to itself" } */ |