https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68782

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think the problem is constexpr.c creates invalid trees, in particular
CONSTRUCTORs that have non-TREE_CONSTANT elements, yet they have TREE_CONSTANT
set on them (and possibly also TREE_SIDE_EFFECTS similarly).
build_constructor with NULL vals creates TREE_CONSTANT and !TREE_SIDE_EFFECTS
CONSTRUCTOR, and constexpr.c later modifies the elts without updating those
flags.

--- constexpr.c.jj4     2015-12-07 12:17:56.000000000 +0100
+++ constexpr.c 2015-12-14 19:40:24.054131253 +0100
@@ -2174,6 +2174,8 @@ cxx_eval_bare_aggregate (const constexpr
 {
   vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
   bool changed = false;
+  bool constant_p = true;
+  bool side_effects_p = false;
   gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));

   verify_ctor_sanity (ctx, TREE_TYPE (t));
@@ -2222,7 +2224,13 @@ cxx_eval_bare_aggregate (const constexpr
          (*p)->last().value = elt;
        }
       else
-       CONSTRUCTOR_APPEND_ELT (*p, index, elt);
+       {
+         CONSTRUCTOR_APPEND_ELT (*p, index, elt);
+         if (!TREE_CONSTANT (elt))
+           constant_p = false;
+         if (TREE_SIDE_EFFECTS (elt))
+           side_effects_p = true;
+       }
     }
   if (*non_constant_p || !changed)
     return t;
@@ -2230,6 +2238,10 @@ cxx_eval_bare_aggregate (const constexpr
   /* We're done building this CONSTRUCTOR, so now we can interpret an
      element without an explicit initializer as value-initialized.  */
   CONSTRUCTOR_NO_IMPLICIT_ZERO (t) = false;
+  if (!constant_p)
+    TREE_CONSTANT (t) = false;
+  if (side_effects_p)
+    TREE_SIDE_EFFECTS (t) = true;
   if (VECTOR_TYPE_P (TREE_TYPE (t)))
     t = fold (t);
   return t;
@@ -2847,9 +2859,13 @@ cxx_eval_store_expression (const constex
       /* The hash table might have moved since the get earlier.  */
       valp = ctx->values->get (object);
       if (TREE_CODE (init) == CONSTRUCTOR)
-       /* An outer ctx->ctor might be pointing to *valp, so just replace
-          its contents.  */
-       CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
+       {
+         /* An outer ctx->ctor might be pointing to *valp, so just replace
+            its contents.  */
+         CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
+         TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
+         TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
+       }
       else
        *valp = init;
     }

is untested fix that cures this testcase, but the cxx_eval_bare_aggregate
changes are incomplete, there are other ways how a new elt is stored too.  Or
perhaps it could just in another loop go over all elements and compute those
flags.  Jason, any thoughts on this?

Reply via email to