On 12/08/2017 11:15 AM, Jakub Jelinek wrote:
Hi!
Martin's patch a few years ago started allowing flexible array members
inside of nested aggregates, similarly to what we were doing in C.
But C rejects cases where we in nested context try to initialize a flexible
array member with a non-empty initializer, because that is something that
can't really work. Say if a flexible array member is inside of a struct
and we are initializing an array of such structs, we can't really have
each array element with a different width based on how large was the
initializer for a particular element's flexible array member.
After Martin's change, we were accepting those and silently generating bogus
assembly (claiming some size of elements but the initializer really followed
the sizes of what was added there), then I think Nathan added some
verification and since then we usually just ICE on those.
This patch does the similar thing in the C++ FE to what the C FE does, i.e.
allow empty initializers of flexible array members ( {}, not "" as that is
already non-zero size) everywhere, and for others allow them only for the
outermost struct/class/union.
Allowing the empty flexible array members is IMHO useful, people can have
say some general structure that is sometimes used as toplevel object and
can be initialized with arbitrarily sized array, and sometimes just use it
inside other structs or arrays if the array isn't needed.
digest_init_r already had a nested argument, but it wasn't actually the
nesting this patch is looking for, because nested true is already in
processing the CONSTRUCTOR for flexible array member, so I've changed it to
an int that tracks limited depth information (just 0 (former nested ==
false), 1 and 2 (both former nested == true), where 2 is used when we
digest_init_r once or more times more).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-12-08 Jakub Jelinek <ja...@redhat.com>
PR c++/80135
PR c++/81922
* typeck2.c (digest_init_r): Change nested argument type from bool to
int. Use code instead of TREE_CODE (type) where possible. If
nested == 2, diagnose initialization of flexible array member with
STRING_CST. Pass nested to process_init_constructor. Formatting fix.
(digest_init, digest_init_flags): Adjust digest_init_r caller.
(massage_init_elt): Add nested argument. Pass 2 instead of 1 to
digest_init_r's nested argument if nested is non-zero.
(process_init_constructor_array): Add nested argument. If nested == 2,
diagnose initialization of flexible array member with non-empty
braced enclosed list. Pass nested to massage_init_elt.
(process_init_constructor_record, process_init_constructor_union): Add
nested argument, pass it to massage_init_elt.
(process_init_constructor): Add nested argument, pass it to
process_init_constructor_{array,record,union}.
* init.c (find_field_init): Return NULL_TREE if init is
error_mark_node. Don't look through nested CONSTRUCTORs.
So this change is because the caller is only interested in flexible
arrays, which can't be deeply nested anymore? In that case, this is no
longer a general purpose function and should be called find_flexarray_init.
OK with that change.
Jason