From 7b3a9795438b33a0137b47f422a9542c5e2d7ccc Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 3 Jun 2015 16:54:24 +0000 Subject: [PATCH] =?utf8?q?re=20PR=20sanitizer/66190=20(ICE:=20tree=20code?= =?utf8?q?=20=E2=80=98call=5Fexpr=E2=80=99=20is=20not=20supported=20in=20L?= =?utf8?q?TO=20streams=20with=20-fsanitize=3Dnull)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-gimplify.c | 24 +++++++++++++++++++--- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/ubsan/static-init-1.C | 21 +++++++++++++++++++ gcc/testsuite/g++.dg/ubsan/static-init-2.C | 17 +++++++++++++++ gcc/testsuite/g++.dg/ubsan/static-init-3.C | 19 +++++++++++++++++ 6 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/static-init-1.C create mode 100644 gcc/testsuite/g++.dg/ubsan/static-init-2.C create mode 100644 gcc/testsuite/g++.dg/ubsan/static-init-3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fe1f7bb03d1..a4ab191ad8c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-06-03 Marek Polacek + + 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 * decl.c (start_function): Call plugin before parsing. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index d5a64fc667f..69fd53b5b28 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -906,6 +906,7 @@ struct cp_genericize_data vec 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 a1d74917010..b5d882df0c9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-06-03 Marek Polacek + + 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 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 00000000000..36c60077ce1 --- /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 00000000000..d046b330b85 --- /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 00000000000..7fd6cbd036a --- /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'" } -- 2.30.2