re PR c++/83556 (ICE in gimplify_expr, at gimplify.c:12004)
authorJakub Jelinek <jakub@redhat.com>
Tue, 2 Jan 2018 18:04:19 +0000 (19:04 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 2 Jan 2018 18:04:19 +0000 (19:04 +0100)
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.

From-SVN: r256086

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

index 985f8716f7497c9f4cec93edc7cafba9100bdf9e..a0da31c6481f62441e043fc229c2481ea2b078a4 100644 (file)
@@ -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.
+
 2018-01-02  Nathan Sidwell  <nathan@acm.org>
 
        * constexpr.c (cxx_bind_parameters_in_call): Remove unneeded local
index 5528fa96fb72b5ded7a574a0bea2994cb9f80f34..37f54847e62212d9c53a900d1171abcf69b267dc 100644 (file)
@@ -3106,6 +3106,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;
@@ -3125,7 +3130,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;
@@ -3133,6 +3138,8 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
       }
 
     default:
+      if (d->pset->add (*t))
+       *walk_subtrees = false;
       break;
     }
 
@@ -3161,7 +3168,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;
index b77e73f8bbc8f9c7a1156f1e853e502316ee2690..684a99355a4ab7b394504212fa7fd16bba0219ac 100644 (file)
@@ -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/45689
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr83556.C b/gcc/testsuite/g++.dg/cpp0x/pr83556.C
new file mode 100644 (file)
index 0000000..bab06a5
--- /dev/null
@@ -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 ();
+}