aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-09-22 20:55:21 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-09-22 20:55:21 +0200
commit2dc589be3cb487eda8f537c535cab0f5a9a4a6a1 (patch)
treee20eb730d1aa94bba5c78eaacfb5b7e5fd413900 /gcc
parentc90df0d293367452d193f04a18c2233d64a10d1a (diff)
downloadgcc-2dc589be3cb487eda8f537c535cab0f5a9a4a6a1.zip
gcc-2dc589be3cb487eda8f537c535cab0f5a9a4a6a1.tar.gz
gcc-2dc589be3cb487eda8f537c535cab0f5a9a4a6a1.tar.bz2
re PR sanitizer/81929 (exponential slowdown in undefined behavior sanitizer for streaming)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/tree.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ubsan/pr81929.C14
4 files changed, 35 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7705321..6288dca 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f387f38..e21ff6a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 54723c2..7c51045 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..90f2628
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr81929.C
@@ -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 ();
+}