f36e50e
2017-12-23  Jakub Jelinek  <jakub@redhat.com>
f36e50e
f36e50e
	PR c++/83556
f36e50e
	* tree.c (replace_placeholders_r): Pass NULL as last argument to
f36e50e
	cp_walk_tree instead of d->pset.  If non-TREE_CONSTANT and
f36e50e
	non-PLACEHOLDER_EXPR tree has been seen already, set *walk_subtrees
f36e50e
	to false and return.
f36e50e
	(replace_placeholders): Pass NULL instead of &pset as last argument
f36e50e
	to cp_walk_tree.
f36e50e
f36e50e
	* g++.dg/cpp0x/pr83556.C: New test.
f36e50e
f36e50e
--- gcc/cp/tree.c.jj	2017-12-15 16:10:37.000000000 +0100
f36e50e
+++ gcc/cp/tree.c	2017-12-22 23:24:16.720428548 +0100
f36e50e
@@ -3106,6 +3106,11 @@ replace_placeholders_r (tree* t, int* wa
f36e50e
       {
f36e50e
 	constructor_elt *ce;
f36e50e
 	vec<constructor_elt,va_gc> *v = CONSTRUCTOR_ELTS (*t);
f36e50e
+	if (d->pset->add (*t))
f36e50e
+	  {
f36e50e
+	    *walk_subtrees = false;
f36e50e
+	    return NULL_TREE;
f36e50e
+	  }
f36e50e
 	for (unsigned i = 0; vec_safe_iterate (v, i, &ce); ++i)
f36e50e
 	  {
f36e50e
 	    tree *valp = &ce->value;
f36e50e
@@ -3125,7 +3130,7 @@ replace_placeholders_r (tree* t, int* wa
f36e50e
 		  valp = &TARGET_EXPR_INITIAL (*valp);
f36e50e
 	      }
f36e50e
 	    d->obj = subob;
f36e50e
-	    cp_walk_tree (valp, replace_placeholders_r, data_, d->pset);
f36e50e
+	    cp_walk_tree (valp, replace_placeholders_r, data_, NULL);
f36e50e
 	    d->obj = obj;
f36e50e
 	  }
f36e50e
 	*walk_subtrees = false;
f36e50e
@@ -3133,6 +3138,8 @@ replace_placeholders_r (tree* t, int* wa
f36e50e
       }
f36e50e
 
f36e50e
     default:
f36e50e
+      if (d->pset->add (*t))
f36e50e
+	*walk_subtrees = false;
f36e50e
       break;
f36e50e
     }
f36e50e
 
f36e50e
@@ -3161,7 +3168,7 @@ replace_placeholders (tree exp, tree obj
f36e50e
   replace_placeholders_t data = { obj, false, &pset };
f36e50e
   if (TREE_CODE (exp) == TARGET_EXPR)
f36e50e
     tp = &TARGET_EXPR_INITIAL (exp);
f36e50e
-  cp_walk_tree (tp, replace_placeholders_r, &data, &pset);
f36e50e
+  cp_walk_tree (tp, replace_placeholders_r, &data, NULL);
f36e50e
   if (seen_p)
f36e50e
     *seen_p = data.seen;
f36e50e
   return exp;
f36e50e
--- gcc/testsuite/g++.dg/cpp0x/pr83556.C.jj	2017-12-22 23:30:10.771126002 +0100
f36e50e
+++ gcc/testsuite/g++.dg/cpp0x/pr83556.C	2017-12-22 23:29:21.000000000 +0100
f36e50e
@@ -0,0 +1,28 @@
f36e50e
+// PR c++/83556
f36e50e
+// { dg-do run { target c++11 } }
f36e50e
+
f36e50e
+int
f36e50e
+foo ()
f36e50e
+{
f36e50e
+  return 1;
f36e50e
+}
f36e50e
+
f36e50e
+struct A
f36e50e
+{
f36e50e
+  int a = foo ();
f36e50e
+  int b = 1;
f36e50e
+  int c = a ? 1 * b : 2 * b;
f36e50e
+};
f36e50e
+
f36e50e
+struct B
f36e50e
+{
f36e50e
+  A d {};
f36e50e
+};
f36e50e
+
f36e50e
+int
f36e50e
+main ()
f36e50e
+{
f36e50e
+  B e {};
f36e50e
+  if (e.d.c != 1)
f36e50e
+    __builtin_abort ();
f36e50e
+}