@@ -9267,6 +9267,17 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
/* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x. */
DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x);
+ /* Set TYPE_INCLUDES_FLEXARRAY for the context of x, t.
+ when x is an array and is the last field. */
+ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+ TYPE_INCLUDES_FLEXARRAY (t)
+ = is_last_field && flexible_array_member_type_p (TREE_TYPE (x));
+ /* Recursively set TYPE_INCLUDES_FLEXARRAY for the context of x, t
+ when x is an union or record and is the last field. */
+ else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
+ TYPE_INCLUDES_FLEXARRAY (t)
+ = is_last_field && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (x));
+
if (DECL_NAME (x)
|| RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
saw_named_field = true;
@@ -1275,7 +1275,10 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (AGGREGATE_TYPE_P (t1))
compare_values (TYPE_TYPELESS_STORAGE);
compare_values (TYPE_EMPTY_P);
- compare_values (TYPE_NO_NAMED_ARGS_STDARG_P);
+ if (FUNC_OR_METHOD_TYPE_P (t1))
+ compare_values (TYPE_NO_NAMED_ARGS_STDARG_P);
+ if (RECORD_OR_UNION_TYPE_P (t1))
+ compare_values (TYPE_INCLUDES_FLEXARRAY);
compare_values (TYPE_PACKED);
compare_values (TYPE_RESTRICT);
compare_values (TYPE_USER_ALIGN);
@@ -632,6 +632,11 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
&& TYPE_CXX_ODR_P (node))
fputs (" cxx-odr-p", file);
+ if ((code == RECORD_TYPE
+ || code == UNION_TYPE)
+ && TYPE_INCLUDES_FLEXARRAY (node))
+ fputs (" includes-flexarray", file);
+
/* The transparent-union flag is used for different things in
different nodes. */
if ((code == UNION_TYPE || code == RECORD_TYPE)
@@ -1713,6 +1713,8 @@ struct GTY(()) tree_type_common {
unsigned typeless_storage : 1;
unsigned empty_flag : 1;
unsigned indivisible_p : 1;
+ /* TYPE_NO_NAMED_ARGS_STDARG_P for a stdarg function.
+ Or TYPE_INCLUDES_FLEXARRAY for RECORD_TYPE and UNION_TYPE. */
unsigned no_named_args_stdarg_p : 1;
unsigned spare : 1;
@@ -386,7 +386,10 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
if (AGGREGATE_TYPE_P (expr))
TYPE_TYPELESS_STORAGE (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_EMPTY_P (expr) = (unsigned) bp_unpack_value (bp, 1);
- TYPE_NO_NAMED_ARGS_STDARG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ if (FUNC_OR_METHOD_TYPE_P (expr))
+ TYPE_NO_NAMED_ARGS_STDARG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ if (RECORD_OR_UNION_TYPE_P (expr))
+ TYPE_INCLUDES_FLEXARRAY (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
SET_TYPE_ALIGN (expr, bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
@@ -355,7 +355,10 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
if (AGGREGATE_TYPE_P (expr))
bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
bp_pack_value (bp, TYPE_EMPTY_P (expr), 1);
- bp_pack_value (bp, TYPE_NO_NAMED_ARGS_STDARG_P (expr), 1);
+ if (FUNC_OR_METHOD_TYPE_P (expr))
+ bp_pack_value (bp, TYPE_NO_NAMED_ARGS_STDARG_P (expr), 1);
+ if (RECORD_OR_UNION_TYPE_P (expr))
+ bp_pack_value (bp, TYPE_INCLUDES_FLEXARRAY (expr), 1);
bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
}
@@ -807,7 +807,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
(...) prototype, where arguments can be accessed with va_start and
va_arg), as opposed to an unprototyped function. */
#define TYPE_NO_NAMED_ARGS_STDARG_P(NODE) \
- (TYPE_CHECK (NODE)->type_common.no_named_args_stdarg_p)
+ (FUNC_OR_METHOD_CHECK (NODE)->type_common.no_named_args_stdarg_p)
+
+/* True if this RECORD_TYPE or UNION_TYPE includes a flexible array member
+ as the last field recursively. */
+#define TYPE_INCLUDES_FLEXARRAY(NODE) \
+ (RECORD_OR_UNION_CHECK (NODE)->type_common.no_named_args_stdarg_p)
/* In an IDENTIFIER_NODE, this means that assemble_name was called with
this string as an argument. */