summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2018-01-02 18:07:41 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2018-01-02 18:07:41 +0000
commitc76d99be43c34683393744898fe1090b3d524a99 (patch)
treea3e520298637639c8b05c1ac35fd01858c66bc04
parent1ef78fadd6d1af603a407bb2180535d52200ef4c (diff)
PR c++/83556
* tree.c (replace_placeholders_r): Pass NULL as last argument to cp_walk_tree instead of d->pset. If non-TREE_CONSTANT and non-PLACEHOLDER_EXPR tree has been seen already, set *walk_subtrees to false and return. (replace_placeholders): Pass NULL instead of &pset as last argument to cp_walk_tree. * g++.dg/cpp0x/pr83556.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@256087 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr83556.C28
4 files changed, 52 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d77663a88d49..99b594717d2b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2018-01-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/83556
+ * tree.c (replace_placeholders_r): Pass NULL as last argument to
+ cp_walk_tree instead of d->pset. If non-TREE_CONSTANT and
+ non-PLACEHOLDER_EXPR tree has been seen already, set *walk_subtrees
+ to false and return.
+ (replace_placeholders): Pass NULL instead of &pset as last argument
+ to cp_walk_tree.
+
2017-12-19 Marek Polacek <polacek@redhat.com>
Backported from mainline
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a5f7f44200c1..6501f127d7cb 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2804,6 +2804,11 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
{
constructor_elt *ce;
vec<constructor_elt,va_gc> *v = CONSTRUCTOR_ELTS (*t);
+ if (d->pset->add (*t))
+ {
+ *walk_subtrees = false;
+ return NULL_TREE;
+ }
for (unsigned i = 0; vec_safe_iterate (v, i, &ce); ++i)
{
tree *valp = &ce->value;
@@ -2823,7 +2828,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_, d->pset);
+ cp_walk_tree (valp, replace_placeholders_r, data_, NULL);
d->obj = obj;
}
*walk_subtrees = false;
@@ -2831,6 +2836,8 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
}
default:
+ if (d->pset->add (*t))
+ *walk_subtrees = false;
break;
}
@@ -2859,7 +2866,7 @@ replace_placeholders (tree exp, tree obj, bool *seen_p)
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, &pset);
+ cp_walk_tree (tp, replace_placeholders_r, &data, NULL);
if (seen_p)
*seen_p = data.seen;
return exp;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d2a588719f79..d7298b8be552 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-01-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/83556
+ * g++.dg/cpp0x/pr83556.C: New test.
+
2018-01-02 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/83650
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83556.C b/gcc/testsuite/g++.dg/cpp0x/pr83556.C
new file mode 100644
index 000000000000..bab06a5b9435
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr83556.C
@@ -0,0 +1,28 @@
+// PR c++/83556
+// { dg-do run { target c++11 } }
+
+int
+foo ()
+{
+ return 1;
+}
+
+struct A
+{
+ int a = foo ();
+ int b = 1;
+ int c = a ? 1 * b : 2 * b;
+};
+
+struct B
+{
+ A d {};
+};
+
+int
+main ()
+{
+ B e {};
+ if (e.d.c != 1)
+ __builtin_abort ();
+}