diff mbox

[ubsan] Don't try to sanitize shifts outside of functions

Message ID 20130730142853.GJ17022@redhat.com
State New
Headers show

Commit Message

Marek Polacek July 30, 2013, 2:28 p.m. UTC
This is something I've stumbled upon when trying to bootstrap with
-fsanitize=undefined (doesn't work so far...).  It's pretty serious
stuff, but clang doesn't handle it either...  We errored on e.g.
enum e { x = 1 << 1 };
because of the instrumentation.  Fixed by doing the instrumentation only
when current_function_decl != 0.  Perhaps this should be revised later on.

Tested x86_64-pc-linux-gnu, applying to ubsan branch.


	Marek
diff mbox

Patch

diff --git a/gcc/c/ChangeLog.ubsan b/gcc/c/ChangeLog.ubsan
index 58e931f..11d167f 100644
--- a/gcc/c/ChangeLog.ubsan
+++ b/gcc/c/ChangeLog.ubsan
@@ -1,3 +1,8 @@ 
+2013-07-30  Marek Polacek  <polacek@redhat.com>
+
+	* c-typeck.c (build_binary_op): Sanitize only when
+	current_function_decl is not zero.
+
 2013-07-21  Marek Polacek  <polacek@redhat.com>
 
 	* c-typeck.c (build_binary_op): Call c_fully_fold on both
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d0f4b0d..7257166 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -10488,7 +10488,8 @@  build_binary_op (location_t location, enum tree_code code,
 	return error_mark_node;
     }
 
-  if (flag_sanitize & SANITIZE_UNDEFINED)
+  if (flag_sanitize & SANITIZE_UNDEFINED
+      && current_function_decl != 0)
     {
       /* OP0 and/or OP1 might have side-effects.  */
       op0 = c_save_expr (op0);
diff --git a/gcc/cp/ChangeLog.ubsan b/gcc/cp/ChangeLog.ubsan
index 0ab2870..f37ce94 100644
--- a/gcc/cp/ChangeLog.ubsan
+++ b/gcc/cp/ChangeLog.ubsan
@@ -1,3 +1,8 @@ 
+2013-07-30  Marek Polacek  <polacek@redhat.com>
+
+	* typeck.c (cp_build_binary_op): Sanitize only when
+	current_function_decl is not zero.
+
 2013-07-05  Marek Polacek  <polacek@redhat.com>
 
 	* typeck.c (cp_build_binary_op): Add division by zero and shift
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7790830..ebe27e8 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4885,6 +4885,7 @@  cp_build_binary_op (location_t location,
 
   if ((flag_sanitize & SANITIZE_UNDEFINED)
       && !processing_template_decl
+      && current_function_decl != 0
       && (doing_div_or_mod || doing_shift))
     {
       /* OP0 and/or OP1 might have side-effects.  */
diff --git a/gcc/testsuite/ChangeLog.ubsan b/gcc/testsuite/ChangeLog.ubsan
index 453bd61..f3f18f9 100644
--- a/gcc/testsuite/ChangeLog.ubsan
+++ b/gcc/testsuite/ChangeLog.ubsan
@@ -1,3 +1,7 @@ 
+2013-07-30  Marek Polacek  <polacek@redhat.com>
+
+	* c-c++-common/ubsan/const-expr.c: New test.
+
 2013-07-22  Marek Polacek  <polacek@redhat.com>
 
 	* c-c++-common/ubsan/div-by-zero-3.c: Add more testing.
diff --git a/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c
new file mode 100644
index 0000000..f474ec6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+enum e { A = 1 << 1, B, };
+const int arr[] = {
+  1 << 2,
+  1 << 3,
+};
+
+int
+bar (int a, int b)
+{
+  return a >> b;
+}
+
+int
+foo (void)
+{
+  int i = 1;
+  int vla[B << 3];
+  return bar (A, (i <<= 6, i + 2));
+}