On 7/20/26 3:33 AM, Jakub Jelinek wrote:
Hi!
The following patch implements the C++29 P2287R6
Designated-initializers for Base Classes
paper.
One change is during parsing, to match the new designated-initializer-list
grammar, the patch allows non-designated clauses followed by designated
clauses for C++29 (but rejects designated followed by non-designated and
also when using GNU style [0] = designators non-designated by designated
with that GNU array style, while the grammar allows now in theory
{ 1, 2, [3] = 3, [4] = 4 } in theory I think it is undesirable to allow
that mixing, the designated after non-designated has been added solely
for base classes and arrays don't have those).
Agreed.
Another change is in the if (first_desig && cxx_dialect >= cxx29) hunk,
to reject non-designated clause which doesn't appertain to base class
followed by designated clause.
Yes.
Yet another change is the lookup_member as fallback to get_class_binding,
but according to the paper it shouldn't replace it, even if there is
ambiguity, if the designator names a NSDM of current class, that should
be what is used, only if it is an ambiguity inside of base classes there
should be an error.
lookup_member will give an unambiguous result if the current class has a
member of that name regardless of any bases. But this way is fine, too.
And finally, if field for C++29 is from some base class, find out the
corresponding base FIELD_DECL and find out how many consecutive designators
belong to the same FIELD_DECL and recurse. For anonymous aggregates
the recursion is handled slightly differently, we call reshape_init_r
instead of reshape_init_class and reshape_init_class called from it will
stop looking on first field which is not found. reshape_init_r in the
case of designators from a base reports some undesirable errors and where
to stop would mean we'd need to pass for the recursion extra arguments
and treat designators for testing in one spot as belonging to the desired
class and in another again as belonging to the current (i.e. base) class.
It seems unfortunate to need to do all this extra adjustment instead of
handling it by the usual reshaping. If the designator names a base
member, would it work to clear direct_desig (and set field to the base
field) so the existing code recurses like for an anonymous aggr member?
@@ -29406,13 +29406,24 @@ cp_parser_initializer_list (cp_parser* p
}
else if (cxx_dialect >= cxx20
&& first_designator != error_mark_node
- && (!first_designator != !designator))
+ && (!first_designator != !designator)
+ && (cxx_dialect < cxx29
+ || first_designator
+ || TREE_CODE (designator) != IDENTIFIER_NODE))
{
- error_at (loc, "either all initializer clauses should be designated "
- "or none of them should be");
+ if (cxx_dialect < cxx29
+ || TREE_CODE (first_designator
+ ? first_designator
+ : designator) != IDENTIFIER_NODE)
+ error_at (loc, "either all initializer clauses should be "
+ "designated or none of them should be");
Can we make it a -Wc++29-extensions pedwarn in earlier modes?
Jason