aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2015-06-03 16:54:24 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2015-06-03 16:54:24 +0000
commit7b3a9795438b33a0137b47f422a9542c5e2d7ccc (patch)
tree34ec9ec91f1ff814d8b450858e27cb18a4ccf1d4
parent5123acd24138878133e447eb369831caa03d305a (diff)
downloadgcc-7b3a9795438b33a0137b47f422a9542c5e2d7ccc.zip
gcc-7b3a9795438b33a0137b47f422a9542c5e2d7ccc.tar.gz
gcc-7b3a9795438b33a0137b47f422a9542c5e2d7ccc.tar.bz2
re PR sanitizer/66190 (ICE: tree code ‘call_expr’ is not supported in LTO streams with -fsanitize=null)
PR sanitizer/66190 * cp-gimplify.c (struct cp_genericize_data): Add no_sanitize_p. (cp_genericize_r): Don't instrument static initializers. (cp_genericize_tree): Initialize wtd.no_sanitize_p. * g++.dg/ubsan/static-init-1.C: New test. * g++.dg/ubsan/static-init-2.C: New test. * g++.dg/ubsan/static-init-3.C: New test. From-SVN: r224096
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-gimplify.c24
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/ubsan/static-init-1.C21
-rw-r--r--gcc/testsuite/g++.dg/ubsan/static-init-2.C17
-rw-r--r--gcc/testsuite/g++.dg/ubsan/static-init-3.C19
6 files changed, 92 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fe1f7bb..a4ab191 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-03 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/66190
+ * cp-gimplify.c (struct cp_genericize_data): Add no_sanitize_p.
+ (cp_genericize_r): Don't instrument static initializers.
+ (cp_genericize_tree): Initialize wtd.no_sanitize_p.
+
2015-06-02 Andres Tiraboschi <andres.tiraboschi@tallertechnologies.com>
* decl.c (start_function): Call plugin before parsing.
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index d5a64fc..69fd53b 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -906,6 +906,7 @@ struct cp_genericize_data
vec<tree> bind_expr_stack;
struct cp_genericize_omp_taskreg *omp_ctx;
tree try_block;
+ bool no_sanitize_p;
};
/* Perform any pre-gimplification lowering of C++ front end trees to
@@ -1105,6 +1106,21 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
: OMP_CLAUSE_DEFAULT_PRIVATE);
}
}
+ if (flag_sanitize
+ & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
+ {
+ /* The point here is to not sanitize static initializers. */
+ bool no_sanitize_p = wtd->no_sanitize_p;
+ wtd->no_sanitize_p = true;
+ for (tree decl = BIND_EXPR_VARS (stmt);
+ decl;
+ decl = DECL_CHAIN (decl))
+ if (VAR_P (decl)
+ && TREE_STATIC (decl)
+ && DECL_INITIAL (decl))
+ cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
+ wtd->no_sanitize_p = no_sanitize_p;
+ }
wtd->bind_expr_stack.safe_push (stmt);
cp_walk_tree (&BIND_EXPR_BODY (stmt),
cp_genericize_r, data, NULL);
@@ -1275,9 +1291,10 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
if (*stmt_p == error_mark_node)
*stmt_p = size_one_node;
return NULL;
- }
- else if (flag_sanitize
- & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
+ }
+ else if ((flag_sanitize
+ & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
+ && !wtd->no_sanitize_p)
{
if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
&& TREE_CODE (stmt) == NOP_EXPR
@@ -1319,6 +1336,7 @@ cp_genericize_tree (tree* t_p)
wtd.bind_expr_stack.create (0);
wtd.omp_ctx = NULL;
wtd.try_block = NULL_TREE;
+ wtd.no_sanitize_p = false;
cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
delete wtd.p_set;
wtd.bind_expr_stack.release ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a1d7491..b5d882d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-03 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/66190
+ * g++.dg/ubsan/static-init-1.C: New test.
+ * g++.dg/ubsan/static-init-2.C: New test.
+ * g++.dg/ubsan/static-init-3.C: New test.
+
2015-06-03 Uros Bizjak <ubizjak@gmail.com>
PR target/66275
diff --git a/gcc/testsuite/g++.dg/ubsan/static-init-1.C b/gcc/testsuite/g++.dg/ubsan/static-init-1.C
new file mode 100644
index 0000000..36c6007
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/static-init-1.C
@@ -0,0 +1,21 @@
+// PR sanitizer/66190
+// { dg-do compile }
+// { dg-options "-fsanitize=null -std=c++11" }
+
+class A {
+public:
+ void fn1 (int);
+};
+
+class G {
+ ~G ();
+ A t;
+ virtual void fn2 () {
+ static int a;
+ static int &b = a;
+ static int &c (a);
+ static int &d {a};
+ t.fn1 (b);
+ }
+};
+G ::~G () {}
diff --git a/gcc/testsuite/g++.dg/ubsan/static-init-2.C b/gcc/testsuite/g++.dg/ubsan/static-init-2.C
new file mode 100644
index 0000000..d046b33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/static-init-2.C
@@ -0,0 +1,17 @@
+// PR sanitizer/66190
+// { dg-do run }
+// { dg-options "-fsanitize=null -std=c++11" }
+
+int
+main ()
+{
+ static int *a;
+ static int &b = *a;
+ static int &c (*a);
+ static int &d {*a};
+ return 0;
+}
+
+// { dg-output "reference binding to null pointer of type 'int'(\n|\r\n|\r)" }
+// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'(\n|\r\n|\r)" }
+// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'" }
diff --git a/gcc/testsuite/g++.dg/ubsan/static-init-3.C b/gcc/testsuite/g++.dg/ubsan/static-init-3.C
new file mode 100644
index 0000000..7fd6cbd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/static-init-3.C
@@ -0,0 +1,19 @@
+// PR sanitizer/66190
+// { dg-do run }
+// { dg-options "-fsanitize=null -std=c++11" }
+
+int *fn (void) { return 0; }
+
+int
+main ()
+{
+ static int a;
+ static int &b = *fn ();
+ static int &c (*fn ());
+ static int &d {*fn ()};
+ return 0;
+}
+
+// { dg-output "reference binding to null pointer of type 'int'(\n|\r\n|\r)" }
+// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'(\n|\r\n|\r)" }
+// { dg-output "\[^\n\r]*reference binding to null pointer of type 'int'" }