diff options
author | Marek Polacek <polacek@redhat.com> | 2015-06-03 16:54:24 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2015-06-03 16:54:24 +0000 |
commit | 7b3a9795438b33a0137b47f422a9542c5e2d7ccc (patch) | |
tree | 34ec9ec91f1ff814d8b450858e27cb18a4ccf1d4 | |
parent | 5123acd24138878133e447eb369831caa03d305a (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/static-init-1.C | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/static-init-2.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ubsan/static-init-3.C | 19 |
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'" } |