@@ -9471,11 +9471,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
if (flexible_array_member_type_p (TREE_TYPE (x)))
{
if (TREE_CODE (t) == UNION_TYPE)
- {
- error_at (DECL_SOURCE_LOCATION (x),
- "flexible array member in union");
- TREE_TYPE (x) = error_mark_node;
- }
+ pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+ "flexible array member in union is a GCC extension");
else if (!is_last_field)
{
error_at (DECL_SOURCE_LOCATION (x),
@@ -9483,12 +9480,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
TREE_TYPE (x) = error_mark_node;
}
else if (!saw_named_field)
- {
- error_at (DECL_SOURCE_LOCATION (x),
- "flexible array member in a struct with no named "
- "members");
- TREE_TYPE (x) = error_mark_node;
- }
+ pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+ "flexible array member in a struct with no named "
+ "members is a GCC extension");
}
if (pedantic && TREE_CODE (t) == RECORD_TYPE
@@ -7624,6 +7624,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
bool diagd = false;
const char *msg = 0;
+ const char *msg_fam = 0;
if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
{
@@ -7649,15 +7650,19 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
if (fmem->after[0])
msg = G_("flexible array member %qD not at end of %q#T");
else if (!fmem->first)
- msg = G_("flexible array member %qD in an otherwise empty %q#T");
+ msg_fam = G_("flexible array member %qD in an otherwise"
+ " empty %q#T is a GCC extension");
- if (msg)
+ if (msg || msg_fam)
{
location_t loc = DECL_SOURCE_LOCATION (fmem->array);
diagd = true;
auto_diagnostic_group d;
- error_at (loc, msg, fmem->array, t);
+ if (msg)
+ error_at (loc, msg, fmem->array, t);
+ else
+ pedwarn (loc, OPT_Wpedantic, msg_fam, fmem->array, t);
/* In the unlikely event that the member following the flexible
array member is declared in a different class, or the member
@@ -14566,10 +14566,9 @@ grokdeclarator (const cp_declarator *declarator,
if (ctype
&& (TREE_CODE (ctype) == UNION_TYPE
|| TREE_CODE (ctype) == QUAL_UNION_TYPE))
- {
- error_at (id_loc, "flexible array member in union");
- type = error_mark_node;
- }
+ pedwarn (id_loc, OPT_Wpedantic,
+ "flexible array member in union is a GCC extension");
+
else
{
/* Array is a flexible member. */
@@ -1245,13 +1245,18 @@ place_union_field (record_layout_info rli, tree field)
&& TYPE_TYPELESS_STORAGE (TREE_TYPE (field)))
TYPE_TYPELESS_STORAGE (rli->t) = 1;
+ /* We might see a flexible array member field (with no DECL_SIZE_UNIT), use
+ zero size for such field. */
+ tree field_size_unit = DECL_SIZE_UNIT (field)
+ ? DECL_SIZE_UNIT (field)
+ : build_int_cst (sizetype, 0);
/* We assume the union's size will be a multiple of a byte so we don't
bother with BITPOS. */
if (TREE_CODE (rli->t) == UNION_TYPE)
- rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
+ rli->offset = size_binop (MAX_EXPR, rli->offset, field_size_unit);
else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
rli->offset = fold_build3 (COND_EXPR, sizetype, DECL_QUALIFIER (field),
- DECL_SIZE_UNIT (field), rli->offset);
+ field_size_unit, rli->offset);
}
/* A bitfield of SIZE with a required access alignment of ALIGN is allocated