@@ -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"));