diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 05d97a7..6232070 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6721,10 +6721,6 @@ struct flexmems_t }; */ tree after[2]; - - /* The type in which an anonymous struct or union containing ARRAY - is defined or null if no such anonymous struct or union exists. */ - tree anonctx; }; /* Find either the first flexible array member or the first zero-length @@ -6826,14 +6822,9 @@ find_flexarrays (tree t, flexmems_t *fmem, bool base_p, find_flexarrays (eltype, fmem, false, pun); if (fmem->array != array) - { - /* If the member struct contains the first flexible array - member, store the enclosing struct if it is anonymous. */ - if (anon_p) - fmem->anonctx = t; - continue; - } - else if (first && !array && !anon_p) + continue; + + if (first && !array && !anon_p) { /* Restore the FIRST member reset above if no flexible array member has been found in this member's struct. */ @@ -6904,6 +6895,22 @@ find_flexarrays (tree t, flexmems_t *fmem, bool base_p, } } +/* Return the type in which the member T is effectively declared in. + This is either the member's enclosing struct for ordinary members, + or for anonymous structs and unions, the first non-anonymou struct + or union they are declared in. */ + +static tree +anon_context (tree t) +{ + if (TREE_CODE (t) == FIELD_DECL) + return anon_context (DECL_CONTEXT (t)); + + bool anon_p = ANON_AGGR_TYPE_P (t); + + return anon_p ? anon_context (TYPE_CONTEXT (t)) : t; +} + /* Issue diagnostics for invalid flexible array members or zero-length arrays that are not the last elements of the containing class or its base classes or that are its sole members. */ @@ -6913,7 +6920,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) { /* Members of anonymous structs and unions are considered to be members of the containing struct or union. */ - if (!fmem->array) + if (!fmem->array || (fmem->first && !fmem->after[0] && !fmem->after[1])) return; /* Issue errors first, and when no errors are found, then warnings @@ -6923,7 +6930,10 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) /* The context of the flexible array member. Either the struct in which it's declared or, for anonymous structs and unions, the struct/union of which the array is effectively a member. */ - tree fmemctx = fmem->anonctx ? fmem->anonctx : t; + tree fmemctx = anon_context (fmem->array); + bool anon_p = fmemctx != DECL_CONTEXT (fmem->array); + if (!anon_p) + fmemctx = t; const char *msg = 0; @@ -6931,7 +6941,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) { if (fmem->after[in_union]) msg = (in_union - ? (fmem->anonctx + ? (anon_p ? G_("zero-size array member %qD belonging to %q#T") : G_("zero-size array member %qD")) : G_("zero-size array member %qD not at end of %q#T")); @@ -6970,7 +6980,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem) { if (fmem->after[in_union]) msg = (in_union - ? (fmem->anonctx + ? (anon_p ? G_("flexible array member %qD belonging to %q#T") : G_("flexible array member %qD")) : G_("flexible array member %qD not at end of %q#T"));