aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2017-09-04 11:30:26 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2017-09-04 11:30:26 +0000
commit8d2b48ae9f3e1e70dfe2aaf32abb9e74594b8875 (patch)
tree9b9eb5195184349428955b9bc16261b81fef83bb
parente910a9b11a04d37e2a9a92dd2bc39097728f132c (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/convert.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr82072.c19
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" } */