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.
This commit is contained in:
parent
64ba45c76e
commit
84fd1b5dff
3 changed files with 46 additions and 30 deletions
|
@ -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. */
|
||||
|
|
|
@ -1517,19 +1517,6 @@ process_init_constructor_record (tree type, tree init, int nested, int flags,
|
|||
|| identifier_p (ce->index));
|
||||
if (ce->index == field || ce->index == DECL_NAME (field))
|
||||
next = ce->value;
|
||||
else if (ANON_AGGR_TYPE_P (fldtype)
|
||||
&& search_anon_aggr (fldtype,
|
||||
TREE_CODE (ce->index) == FIELD_DECL
|
||||
? DECL_NAME (ce->index)
|
||||
: ce->index))
|
||||
/* 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. */
|
||||
next = build_constructor_single (init_list_type_node,
|
||||
ce->index, ce->value);
|
||||
else
|
||||
{
|
||||
ce = NULL;
|
||||
|
@ -1675,19 +1662,6 @@ process_init_constructor_record (tree type, tree init, int nested, int flags,
|
|||
|
||||
if (ce->index == field || ce->index == DECL_NAME (field))
|
||||
break;
|
||||
if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
tree t
|
||||
= search_anon_aggr (TREE_TYPE (field),
|
||||
TREE_CODE (ce->index) == FIELD_DECL
|
||||
? DECL_NAME (ce->index)
|
||||
: ce->index);
|
||||
if (t)
|
||||
{
|
||||
field = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field)
|
||||
|
|
17
gcc/testsuite/g++.dg/cpp2a/desig18.C
Normal file
17
gcc/testsuite/g++.dg/cpp2a/desig18.C
Normal file
|
@ -0,0 +1,17 @@
|
|||
// PR c++/100489
|
||||
// { dg-options "" }
|
||||
|
||||
union U
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char a;
|
||||
};
|
||||
|
||||
unsigned char b[1];
|
||||
};
|
||||
|
||||
void f(unsigned char a)
|
||||
{
|
||||
union U u = { .a = a };
|
||||
}
|
Loading…
Add table
Reference in a new issue