Once a CONSTRUCTOR has been digested and used as an initializer, it no
longer represents a compound literal by itself, so we can clear the flag,
letting us use it consistently to distinguish between digested and
undigested initializer-lists.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

        * pt.c (get_template_parm_object): Add assert.
        * semantics.c (finish_compound_literal): Clear TREE_HAS_CONSTRUCTOR.
        * tree.c (zero_init_expr_p): Check TREE_HAS_CONSTRUCTOR.
        * typeck2.c (store_init_value): Likewise.
---
 gcc/cp/cp-tree.h   | 6 ++++--
 gcc/cp/pt.c        | 2 +-
 gcc/cp/semantics.c | 8 ++++++--
 gcc/cp/tree.c      | 8 ++------
 gcc/cp/typeck2.c   | 6 ++++++
 5 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cb254e0adea..e80902a2139 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4407,7 +4407,7 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
    When appearing in a SAVE_EXPR, it means that underneath
    is a call to a constructor.
 
-   When appearing in a CONSTRUCTOR, the expression is a
+   When appearing in a CONSTRUCTOR, the expression is an unconverted
    compound literal.
 
    When appearing in a FIELD_DECL, it means that this field
@@ -4419,7 +4419,9 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
   (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node)
 
 /* True if NODE is a compound-literal, i.e., a brace-enclosed
-   initializer cast to a particular type.  */
+   initializer cast to a particular type.  This is mostly only set during
+   template parsing; once the initializer has been digested into an actual
+   value of the type, the expression is represented by a TARGET_EXPR.  */
 #define COMPOUND_LITERAL_P(NODE) \
   (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE))
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eaf46659f85..3cd803f2f81 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7157,7 +7157,7 @@ get_template_parm_object (tree expr, tsubst_flags_t 
complain)
     return error_mark_node;
 
   /* This is no longer a compound literal.  */
-  TREE_HAS_CONSTRUCTOR (expr) = 0;
+  gcc_assert (!TREE_HAS_CONSTRUCTOR (expr));
 
   tree name = mangle_template_parm_object (expr);
   tree decl = get_global_binding (name);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3a6468fd5f3..319a3a816ed 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3177,9 +3177,13 @@ finish_compound_literal (tree type, tree 
compound_literal,
     }
 
   /* Represent other compound literals with TARGET_EXPR so we produce
-     an lvalue, but can elide copies.  */
+     a prvalue, and can elide copies.  */
   if (!VECTOR_TYPE_P (type))
-    compound_literal = get_target_expr_sfinae (compound_literal, complain);
+    {
+      /* The CONSTRUCTOR is now an initializer, not a compound literal.  */
+      TREE_HAS_CONSTRUCTOR (compound_literal) = false;
+      compound_literal = get_target_expr_sfinae (compound_literal, complain);
+    }
 
   return compound_literal;
 }
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a8bfd5fc053..3a20cd33fdc 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4684,13 +4684,9 @@ zero_init_expr_p (tree t)
     return null_member_pointer_value_p (t);
   if (TREE_CODE (t) == CONSTRUCTOR)
     {
-      if (CONSTRUCTOR_IS_DEPENDENT (t)
+      if (COMPOUND_LITERAL_P (t)
          || BRACE_ENCLOSED_INITIALIZER_P (t))
-       /* Undigested, conversions might change the zeroness.
-
-          Other COMPOUND_LITERAL_P in template context are also undigested,
-          but there isn't currently a way to distinguish between them and
-          COMPOUND_LITERAL_P from non-template context that are digested.  */
+       /* Undigested, conversions might change the zeroness.  */
        return false;
       for (constructor_elt &elt : CONSTRUCTOR_ELTS (t))
        {
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 4e9632f6a7d..ce3016c780d 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -818,6 +818,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** 
cleanups, int flags)
   /* Handle aggregate NSDMI in non-constant initializers, too.  */
   value = replace_placeholders (value, decl);
 
+  /* A COMPOUND_LITERAL_P CONSTRUCTOR is the syntactic form; by the time we get
+     here it should have been digested into an actual value for the type.  */
+  gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR
+                      || processing_template_decl
+                      || !TREE_HAS_CONSTRUCTOR (value));
+
   /* If the initializer is not a constant, fill in DECL_INITIAL with
      the bits that are constant, and then return an expression that
      will perform the dynamic initialization.  */

base-commit: 449d7b40f6f6be8d7f9aa7232c73b0371f0963bf
-- 
2.27.0

Reply via email to