aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2013-09-25 08:58:57 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2013-09-25 08:58:57 +0000
commitb56e978833b09ba47ebc4ebdace007164b493266 (patch)
tree083cf293ac56951841b59e2db56b5176d154c73a /gcc
parent550dfe7f28a031f5ffe59c423c7790d219414ff6 (diff)
downloadgcc-b56e978833b09ba47ebc4ebdace007164b493266.zip
gcc-b56e978833b09ba47ebc4ebdace007164b493266.tar.gz
gcc-b56e978833b09ba47ebc4ebdace007164b493266.tar.bz2
re PR sanitizer/58413 (ubsan constant folding)
PR sanitizer/58413 c-family/ * c-ubsan.c (ubsan_instrument_shift): Don't instrument an expression if we can prove it is correct. (ubsan_instrument_division): Likewise. Remove unnecessary check. testsuite/ * c-c++-common/ubsan/shift-5.c: New test. * c-c++-common/ubsan/shift-6.c: New test. * c-c++-common/ubsan/div-by-zero-5.c: New test. * gcc.dg/ubsan/c-shift-1.c: New test. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r202886
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c-ubsan.c18
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c8
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-5.c33
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-6.c30
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/c-shift-1.c18
7 files changed, 116 insertions, 8 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1772ba5..c7a8c787 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,12 @@
+2013-09-25 Marek Polacek <polacek@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/58413
+ * c-ubsan.c (ubsan_instrument_shift): Don't instrument
+ an expression if we can prove it is correct.
+ (ubsan_instrument_division): Likewise. Remove unnecessary
+ check.
+
2013-09-18 Marek Polacek <polacek@redhat.com>
PR sanitizer/58411
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
index 9f43f6d..0bfc660 100644
--- a/gcc/c-family/c-ubsan.c
+++ b/gcc/c-family/c-ubsan.c
@@ -51,14 +51,6 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
if (TREE_CODE (type) != INTEGER_TYPE)
return NULL_TREE;
- /* If we *know* that the divisor is not -1 or 0, we don't have to
- instrument this expression.
- ??? We could use decl_constant_value to cover up more cases. */
- if (TREE_CODE (op1) == INTEGER_CST
- && integer_nonzerop (op1)
- && !integer_minus_onep (op1))
- return NULL_TREE;
-
t = fold_build2 (EQ_EXPR, boolean_type_node,
op1, build_int_cst (type, 0));
@@ -74,6 +66,11 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
}
+ /* If the condition was folded to 0, no need to instrument
+ this expression. */
+ if (integer_zerop (t))
+ return NULL_TREE;
+
/* In case we have a SAVE_EXPR in a conditional context, we need to
make sure it gets evaluated before the condition. */
t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
@@ -138,6 +135,11 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
}
+ /* If the condition was folded to 0, no need to instrument
+ this expression. */
+ if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
+ return NULL_TREE;
+
/* In case we have a SAVE_EXPR in a conditional context, we need to
make sure it gets evaluated before the condition. */
t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 68e38cc9..09644d2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,13 @@
2013-09-25 Marek Polacek <polacek@redhat.com>
+ PR sanitizer/58413
+ * c-c++-common/ubsan/shift-5.c: New test.
+ * c-c++-common/ubsan/shift-6.c: New test.
+ * c-c++-common/ubsan/div-by-zero-5.c: New test.
+ * gcc.dg/ubsan/c-shift-1.c: New test.
+
+2013-09-25 Marek Polacek <polacek@redhat.com>
+
PR c++/58516
* g++.dg/tm/pr58516.C: New test.
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c
new file mode 100644
index 0000000..7a28bac
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-5.c
@@ -0,0 +1,8 @@
+/* { dg-do compile} */
+/* { dg-options "-fsanitize=integer-divide-by-zero" } */
+
+void
+foo (void)
+{
+ int A[-2 / -1] = {};
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-5.c b/gcc/testsuite/c-c++-common/ubsan/shift-5.c
new file mode 100644
index 0000000..6f9c52a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-5.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -w" } */
+/* { dg-shouldfail "ubsan" } */
+
+int x;
+int
+foo (void)
+{
+ /* None of the following should pass. */
+ switch (x)
+ {
+ case 1 >> -1:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 12 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 12 } */
+ case -1 >> -1:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 15 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 15 } */
+ case 1 << -1:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 18 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 18 } */
+ case -1 << -1:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 21 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 21 } */
+ case -1 >> 200:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 24 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 24 } */
+ case 1 << 200:
+/* { dg-error "case label does not reduce to an integer constant" "" {target c } 27 } */
+/* { dg-error "is not a constant expression" "" { target c++ } 27 } */
+ return 1;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-6.c b/gcc/testsuite/c-c++-common/ubsan/shift-6.c
new file mode 100644
index 0000000..a0e2e20
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-6.c
@@ -0,0 +1,30 @@
+/* PR sanitizer/58413 */
+/* { dg-do run { target int32plus } } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+int x = 7;
+int
+main (void)
+{
+ /* All of the following should pass. */
+ int A[128 >> 5] = {};
+ int B[128 << 5] = {};
+
+ static int e =
+ ((int)
+ (0x00000000 | ((31 & ((1 << (4)) - 1)) << (((15) + 6) + 4)) |
+ ((0) << ((15) + 6)) | ((0) << (15))));
+
+ if (e != 503316480)
+ __builtin_abort ();
+
+ switch (x)
+ {
+ case 1 >> 4:
+ case 1 << 4:
+ case 128 << (4 + 1):
+ case 128 >> (4 + 1):
+ return 1;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c b/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c
new file mode 100644
index 0000000..61b9010
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/c-shift-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile} */
+/* { dg-options "-fsanitize=shift -w" } */
+/* { dg-shouldfail "ubsan" } */
+
+int x;
+int
+main (void)
+{
+ /* None of the following should pass. */
+ int A[1 >> -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+ int B[-1 >> -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+ int D[1 << -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+ int E[-1 << -1] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+ int F[-1 >> 200] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+ int G[1 << 200] = {}; /* { dg-error "variable-sized object may not be initialized" } */
+
+ return 0;
+}