re PR sanitizer/81929 (exponential slowdown in undefined behavior sanitizer for strea...
authorJakub Jelinek <jakub@redhat.com>
Fri, 22 Sep 2017 18:55:21 +0000 (20:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 22 Sep 2017 18:55:21 +0000 (20:55 +0200)
PR sanitizer/81929
* tree.c (struct replace_placeholders_t): Add pset field.
(replace_placeholders_r): Call cp_walk_tree with d->pset as
last argument instead of NULL.  Formatting fix.
(replace_placeholders): Add pset variable, add its address
into data.  Pass &pset instead of NULL to cp_walk_tree.

* g++.dg/ubsan/pr81929.C: New test.

From-SVN: r253106

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ubsan/pr81929.C [new file with mode: 0644]

index 7705321d9ebcb01d153c422325aa55612589bd78..6288dcaf7279a9480f77f33f3043e03a1f921e62 100644 (file)
@@ -1,3 +1,12 @@
+2017-09-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81929
+       * tree.c (struct replace_placeholders_t): Add pset field.
+       (replace_placeholders_r): Call cp_walk_tree with d->pset as
+       last argument instead of NULL.  Formatting fix.
+       (replace_placeholders): Add pset variable, add its address
+       into data.  Pass &pset instead of NULL to cp_walk_tree.
+
 2017-09-22  David Malcolm  <dmalcolm@redhat.com>
 
        * call.c (get_fndecl_argument_location): New function.
index f387f38639b937e22119aaf658664cff95918189..e21ff6a1572f853a2e772f09dcfb315cfbdb74f2 100644 (file)
@@ -3063,6 +3063,7 @@ struct replace_placeholders_t
 {
   tree obj;        /* The object to be substituted for a PLACEHOLDER_EXPR.  */
   bool seen;       /* Whether we've encountered a PLACEHOLDER_EXPR.  */
+  hash_set<tree> *pset;        /* To avoid walking same trees multiple times.  */
 };
 
 /* Like substitute_placeholder_in_expr, but handle C++ tree codes and
@@ -3085,8 +3086,8 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
     case PLACEHOLDER_EXPR:
       {
        tree x = obj;
-       for (; !(same_type_ignoring_top_level_qualifiers_p
-                (TREE_TYPE (*t), TREE_TYPE (x)));
+       for (; !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (*t),
+                                                          TREE_TYPE (x));
             x = TREE_OPERAND (x, 0))
          gcc_assert (TREE_CODE (x) == COMPONENT_REF);
        *t = x;
@@ -3118,8 +3119,7 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
                  valp = &TARGET_EXPR_INITIAL (*valp);
              }
            d->obj = subob;
-           cp_walk_tree (valp, replace_placeholders_r,
-                         data_, NULL);
+           cp_walk_tree (valp, replace_placeholders_r, data_, d->pset);
            d->obj = obj;
          }
        *walk_subtrees = false;
@@ -3151,10 +3151,11 @@ replace_placeholders (tree exp, tree obj, bool *seen_p)
     return exp;
 
   tree *tp = &exp;
-  replace_placeholders_t data = { obj, false };
+  hash_set<tree> pset;
+  replace_placeholders_t data = { obj, false, &pset };
   if (TREE_CODE (exp) == TARGET_EXPR)
     tp = &TARGET_EXPR_INITIAL (exp);
-  cp_walk_tree (tp, replace_placeholders_r, &data, NULL);
+  cp_walk_tree (tp, replace_placeholders_r, &data, &pset);
   if (seen_p)
     *seen_p = data.seen;
   return exp;
index 54723c2c71ba8ff6575f33c1dc49c72112961377..7c5104512c0ec1c92c295ec5c33984e86f1d13d2 100644 (file)
@@ -1,3 +1,8 @@
+2017-09-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR sanitizer/81929
+       * g++.dg/ubsan/pr81929.C: New test.
+
 2017-09-22  Richard Sandiford  <richard.sandiford@linaro.org>
 
        PR tree-optimization/82289
diff --git a/gcc/testsuite/g++.dg/ubsan/pr81929.C b/gcc/testsuite/g++.dg/ubsan/pr81929.C
new file mode 100644 (file)
index 0000000..90f2628
--- /dev/null
@@ -0,0 +1,14 @@
+// PR sanitizer/81929
+// { dg-do compile }
+// { dg-options "-std=c++14 -fsanitize=undefined" }
+
+struct S { S &operator<< (long); S foo (); S (); };
+
+void
+bar ()
+{
+  static_cast<S&>(S () << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0
+                      << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0
+                      << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0
+                      << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0).foo ();
+}