aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-05-19 21:12:45 -0400
committerJason Merrill <jason@redhat.com>2021-05-20 16:59:17 -0400
commit84fd1b5dff70cd74aee7e8b18f66959d8b8e1ce7 (patch)
tree3584ac15bb2a3eea9a0c8787fc9b66e5bbc4f396 /gcc/cp/decl.c
parent64ba45c76e831914764b70207d69a06f800b43a4 (diff)
downloadgcc-84fd1b5dff70cd74aee7e8b18f66959d8b8e1ce7.zip
gcc-84fd1b5dff70cd74aee7e8b18f66959d8b8e1ce7.tar.gz
gcc-84fd1b5dff70cd74aee7e8b18f66959d8b8e1ce7.tar.bz2
c++: designated init with anonymous union [PR100489]
My patch for PR98463 added an assert that tripped on this testcase, because we ended up with a U CONSTRUCTOR with an initializer for a, which is not a member of U. We need to wrap the a initializer in another CONSTRUCTOR for the anonymous union. There was already support for this in process_init_constructor_record, but not in process_init_constructor_union. But since this is about brace elision, it really belongs under reshape_init rather than digest_init, so this patch moves the handling to reshape_init_class, which also handles unions. PR c++/100489 gcc/cp/ChangeLog: * decl.c (reshape_init_class): Handle designator for member of anonymous aggregate here. * typeck2.c (process_init_constructor_record): Not here. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/desig18.C: New test.
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7c32f09..6107b55 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6418,10 +6418,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
/* We already reshaped this. */
if (field != d->cur->index)
{
- tree id = DECL_NAME (d->cur->index);
- gcc_assert (id);
- gcc_checking_assert (d->cur->index
- == get_class_binding (type, id));
+ if (tree id = DECL_NAME (d->cur->index))
+ gcc_checking_assert (d->cur->index
+ == get_class_binding (type, id));
field = d->cur->index;
}
}
@@ -6442,6 +6441,32 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
d->cur->index);
return error_mark_node;
}
+
+ /* If the element is an anonymous union object and the initializer
+ list is a designated-initializer-list, the anonymous union object
+ is initialized by the designated-initializer-list { D }, where D
+ is the designated-initializer-clause naming a member of the
+ anonymous union object. */
+ tree ictx = DECL_CONTEXT (field);
+ if (!same_type_ignoring_top_level_qualifiers_p (ictx, type))
+ {
+ gcc_assert (ANON_AGGR_TYPE_P (ictx));
+ /* Find the anon aggr that is a direct member of TYPE. */
+ while (true)
+ {
+ tree cctx = TYPE_CONTEXT (ictx);
+ if (same_type_ignoring_top_level_qualifiers_p (cctx, type))
+ break;
+ ictx = cctx;
+ }
+ /* And then the TYPE member with that anon aggr type. */
+ tree aafield = TYPE_FIELDS (type);
+ for (; aafield; aafield = TREE_CHAIN (aafield))
+ if (TREE_TYPE (aafield) == ictx)
+ break;
+ gcc_assert (aafield);
+ field = aafield;
+ }
}
/* If we processed all the member of the class, we are done. */