aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-11-14 11:57:05 +0000
committerMarek Polacek <polacek@redhat.com>2014-11-14 11:57:05 +0000
commitbecd5e1ac92ad5e24222d474970c017b81e99c1d (patch)
treee658bdd67d7d906e29048429d363eaa3f48eaab0
parent726e3122f1b7a5440dcceeac4a69c292e04c23cd (diff)
* fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if
that overflows when SANITIZE_SI_OVERFLOW is on. Guard -(-A) folding with TYPE_OVERFLOW_SANITIZED. * c-c++-common/ubsan/overflow-negate-3.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@217556 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c21
4 files changed, 36 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 58efc772d66..976dd3bf51d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2014-11-14 Marek Polacek <polacek@redhat.com>
+ * fold-const.c (fold_negate_expr): Don't fold INTEGER_CST if
+ that overflows when SANITIZE_SI_OVERFLOW is on. Guard -(-A)
+ folding with TYPE_OVERFLOW_SANITIZED.
+
+2014-11-14 Marek Polacek <polacek@redhat.com>
+
PR sanitizer/63839
* asan.c (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST,
ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST): Define.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0170b88daef..7dbbadd859b 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -554,7 +554,8 @@ fold_negate_expr (location_t loc, tree t)
case INTEGER_CST:
tem = fold_negate_const (t, type);
if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
- || !TYPE_OVERFLOW_TRAPS (type))
+ || (!TYPE_OVERFLOW_TRAPS (type)
+ && (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0))
return tem;
break;
@@ -611,7 +612,9 @@ fold_negate_expr (location_t loc, tree t)
break;
case NEGATE_EXPR:
- return TREE_OPERAND (t, 0);
+ if (!TYPE_OVERFLOW_SANITIZED (type))
+ return TREE_OPERAND (t, 0);
+ break;
case PLUS_EXPR:
if (!HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1d3ef947bf2..b6a07d3fb12 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2014-11-14 Marek Polacek <polacek@redhat.com>
+ * c-c++-common/ubsan/overflow-negate-3.c: New test.
+
+2014-11-14 Marek Polacek <polacek@redhat.com>
+
PR sanitizer/63839
* c-c++-common/ubsan/pr63839.c: New test.
* c-c++-common/ubsan/unreachable-2.c: New test.
diff --git a/gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
new file mode 100644
index 00000000000..e6db394a4f5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/overflow-negate-3.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=signed-integer-overflow" } */
+
+#define INT_MIN (-__INT_MAX__ - 1)
+
+int
+main ()
+{
+ int x = INT_MIN;
+ int y;
+ asm ("" : "+g" (x));
+ y = -(-x);
+ asm ("" : "+g" (y));
+ y = -(-INT_MIN);
+ asm ("" : "+g" (y));
+}
+
+/* { dg-output "negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*negation of -2147483648 cannot be represented in type 'int'\[^\n\r]*; cast to an unsigned type to negate this value to itself\[^\n\r]*(\n|\r\n|\r)" } */