diff options
author | Richard Henderson <rth@redhat.com> | 2001-01-04 21:58:23 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-01-04 21:58:23 -0800 |
commit | ffc5c6a98441d8e1abe6cdc0d2a93591e21191d7 (patch) | |
tree | f0375afbbd6220caa4aacf6320495224ac911480 /gcc/c-typeck.c | |
parent | 00de56c7d0e654b52c23e789dbe3cc32d361a527 (diff) | |
download | gcc-ffc5c6a98441d8e1abe6cdc0d2a93591e21191d7.tar.gz |
c-decl.c (finish_struct): Detect flexible array members used in an inappropriate context.
* c-decl.c (finish_struct): Detect flexible array members
used in an inappropriate context.
* c-typeck.c (really_start_incremental_init): Special case
constructor_max_index for zero length arrays.
(pop_init_level): Allow initialization of flexible array
members. Deprecate initialization of zero length arrays.
Don't issue missing initializer warning for flexible array
members or zero length arrays.
(process_init_element): Don't dereference null DECL_SIZE.
* varasm.c (array_size_for_constructor): Return a HOST_WIDE_INT.
Don't abort for empty constructors. Use size_binop
(output_constructor): Add commentary regarding zero length
array futures. Abort if we try to initialize an array of
unspecified length with a non-empty constructor in the middle
of a structure.
* extend.texi (Zero Length): Update and clarify documentation
on static initialization.
From-SVN: r38705
Diffstat (limited to 'gcc/c-typeck.c')
-rw-r--r-- | gcc/c-typeck.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6a57eed24bd..2868496a53d 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -5162,6 +5162,11 @@ really_start_incremental_init (type) { constructor_max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); + + /* Detect non-empty initializations of zero-length arrays. */ + if (constructor_max_index == NULL_TREE) + constructor_max_index = build_int_2 (-1, -1); + constructor_index = convert (bitsizetype, TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); @@ -5292,6 +5297,11 @@ push_init_level (implicit) constructor_index = convert (bitsizetype, TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); + + /* ??? For GCC 3.1, remove special case initialization of + zero-length array members from pop_init_level and set + constructor_max_index such that we get the normal + "excess elements" warning. */ } else constructor_index = bitsize_zero_node; @@ -5337,20 +5347,42 @@ pop_init_level (implicit) /* Error for initializing a flexible array member, or a zero-length array member in an inappropriate context. */ - if (constructor_type + if (constructor_type && constructor_fields && TREE_CODE (constructor_type) == ARRAY_TYPE && TYPE_DOMAIN (constructor_type) && ! TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type))) { - if (! TYPE_SIZE (constructor_type)) - error_init ("initialization of a flexible array member"); - /* Silently discard empty initializations of zero-length arrays. */ - else if (integer_zerop (constructor_unfilled_index)) - constructor_type = 0; - /* Otherwise we must be initializing a member of a top-level - structure. */ - else if (constructor_depth != 2) - error_init ("initialization of zero-length array inside a nested structure"); + /* Silently discard empty initializations. The parser will + already have pedwarned for empty brackets. */ + if (integer_zerop (constructor_unfilled_index)) + constructor_type = NULL_TREE; + else if (! TYPE_SIZE (constructor_type)) + { + if (constructor_depth > 2) + error_init ("initialization of flexible array member in a nested context"); + else if (pedantic) + pedwarn_init ("initialization of a flexible array member"); + + /* We have already issued an error message for the existance + of a flexible array member not at the end of the structure. + Discard the initializer so that we do not abort later. */ + if (TREE_CHAIN (constructor_fields) != NULL_TREE) + constructor_type = NULL_TREE; + } + else + { + warning_init ("deprecated initialization of zero-length array"); + + /* We must be initializing the last member of a top-level struct. */ + if (TREE_CHAIN (constructor_fields) != NULL_TREE) + { + error_init ("initialization of zero-length array before end of structure"); + /* Discard the initializer so that we do not abort later. */ + constructor_type = NULL_TREE; + } + else if (constructor_depth > 2) + error_init ("initialization of zero-length array inside a nested context"); + } } /* Warn when some struct elements are implicitly initialized to zero. */ @@ -5359,9 +5391,18 @@ pop_init_level (implicit) && TREE_CODE (constructor_type) == RECORD_TYPE && constructor_unfilled_fields) { - push_member_name (constructor_unfilled_fields); - warning_init ("missing initializer"); - RESTORE_SPELLING_DEPTH (constructor_depth); + /* Do not warn for flexible array members or zero-length arrays. */ + while (constructor_unfilled_fields + && (! DECL_SIZE (constructor_unfilled_fields) + || integer_zerop (DECL_SIZE (constructor_unfilled_fields)))) + constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields); + + if (constructor_unfilled_fields) + { + push_member_name (constructor_unfilled_fields); + warning_init ("missing initializer"); + RESTORE_SPELLING_DEPTH (constructor_depth); + } } /* Now output all pending elements. */ @@ -6129,10 +6170,11 @@ process_init_element (value) directly output as a constructor. */ { /* For a record, keep track of end position of last field. */ - constructor_bit_index - = size_binop (PLUS_EXPR, - bit_position (constructor_fields), - DECL_SIZE (constructor_fields)); + if (DECL_SIZE (constructor_fields)) + constructor_bit_index + = size_binop (PLUS_EXPR, + bit_position (constructor_fields), + DECL_SIZE (constructor_fields)); constructor_unfilled_fields = TREE_CHAIN (constructor_fields); /* Skip any nameless bit fields. */ |