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 <[email protected]> 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
