aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-04-15 17:04:24 -0400
committerJason Merrill <jason@redhat.com>2021-04-29 14:33:39 -0400
commit3f0de4dd51fd9a1e9628411b4fd728f5841256fe (patch)
treeaf3e957d72b4b8b8005c81047b611418db51cc84 /gcc
parentefeca0ac4155b76ce713155f190422aac20537c5 (diff)
downloadgcc-3f0de4dd51fd9a1e9628411b4fd728f5841256fe.zip
gcc-3f0de4dd51fd9a1e9628411b4fd728f5841256fe.tar.gz
gcc-3f0de4dd51fd9a1e9628411b4fd728f5841256fe.tar.bz2
c++: unset COMPOUND_LITERAL_P [PR100079]
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. gcc/cp/ChangeLog: * cp-tree.h: Clarify comments. * 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c8
-rw-r--r--gcc/cp/tree.c8
-rw-r--r--gcc/cp/typeck2.c6
5 files changed, 19 insertions, 11 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cb254e0..e80902a 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 4e9b40f..fc5065b 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 3a6468f..319a3a8 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 a8bfd5f..3a20cd3 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 4e9632f..ce3016c 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. */