On 12/08/2017 09: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.
Harmonizing C++ with C was one of my goals when I made those
changes so rejecting the nested initialization makes sense.
I suspect I just missed that C errors out on these and assumed
it allowed them like it does at the top level (rather than
deliberately relaxing the rules), so thank you for tightening
it up.
While testing the patch I noticed it issues some diagnostics
multiple times. It would be nice if the last (redundant)
pedantic warning in the error case below could be avoided.
struct B { int i; struct { int j, a[]; } a; };
struct B g (void)
{
return (struct B){ 1, { 2, { 3 } } };
}
u.C:1:37: warning: ISO C++ forbids flexible array member ‘a’ [-Wpedantic]
struct B { int i; struct { int j, a[]; } a; };
^
u.C:1:42: warning: invalid use of ‘struct B::<unnamed>’ with a flexible
array member in ‘struct B’ [-Wpedantic]
struct B { int i; struct { int j, a[]; } a; };
^
u.C:1:37: note: array member ‘int B::<unnamed struct>::a []’ declared here
struct B { int i; struct { int j, a[]; } a; };
^
u.C: In function ‘B g()’:
u.C:5:38: warning: ISO C++ forbids compound-literals [-Wpedantic]
return (struct B){ 1, { 2, { 3 } } };
^
u.C:5:38: warning: initialization of a flexible array member [-Wpedantic]
u.C:5:38: error: initialization of flexible array member in a nested context
Martin