aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-09-13 20:19:42 +0000
committerRichard Stallman <rms@gnu.org>1993-09-13 20:19:42 +0000
commit94ba50696434bfaf90030d9b51959695accaec0b (patch)
tree960e2e8f443b962db140a9b8c1312ffbc471e382
parentecd4cee03c1299324409ee653b673e8acc84ec58 (diff)
downloadgcc-94ba50696434bfaf90030d9b51959695accaec0b.zip
gcc-94ba50696434bfaf90030d9b51959695accaec0b.tar.gz
gcc-94ba50696434bfaf90030d9b51959695accaec0b.tar.bz2
(set_init_index): Don't allow variable indices.
(output_init_element): When putting an elt into a CONSTRUCTOR, always set the TREE_PURPOSE (even for arrays). Copy the node if it's an INTEGER_CST. (output_pending_init_elements): If have gap and not incremental, advance constructor_unfilled_fields or constructor_unfilled_index. (push_init_level): Pop any implicit levels that have been filled up. Don't die if constructor_type is 0. (process_init_element): If VALUE is 0 for union type, update constructor_bit_index. From-SVN: r5317
-rw-r--r--gcc/c-typeck.c81
1 files changed, 65 insertions, 16 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 250d59e..89767c3 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -5378,8 +5378,24 @@ void
push_init_level (implicit)
int implicit;
{
- struct constructor_stack *p
- = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
+ struct constructor_stack *p;
+
+ /* If we've exhausted any levels that didn't have braces,
+ pop them now. */
+ while (constructor_stack->implicit)
+ {
+ if ((TREE_CODE (constructor_type) == RECORD_TYPE
+ || TREE_CODE (constructor_type) == UNION_TYPE)
+ && constructor_fields == 0)
+ process_init_element (pop_init_level (1));
+ else if (TREE_CODE (constructor_type) == ARRAY_TYPE
+ && tree_int_cst_lt (constructor_max_index, constructor_index))
+ process_init_element (pop_init_level (1));
+ else
+ break;
+ }
+
+ p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
p->type = constructor_type;
p->fields = constructor_fields;
p->index = constructor_index;
@@ -5407,8 +5423,12 @@ push_init_level (implicit)
constructor_elements = 0;
constructor_pending_elts = 0;
- if (TREE_CODE (constructor_type) == RECORD_TYPE
- || TREE_CODE (constructor_type) == UNION_TYPE)
+ /* Don't die if an entire brace-pair level is superfluous
+ in the containing level. */
+ if (constructor_type == 0)
+ ;
+ else if (TREE_CODE (constructor_type) == RECORD_TYPE
+ || TREE_CODE (constructor_type) == UNION_TYPE)
{
/* Don't die if there are extra init elts at the end. */
if (constructor_fields == 0)
@@ -5426,7 +5446,8 @@ push_init_level (implicit)
}
/* Turn off constructor_incremental if type is a struct with bitfields. */
- check_init_type_bitfields (constructor_type);
+ if (constructor_type != 0)
+ check_init_type_bitfields (constructor_type);
if (constructor_type == 0)
{
@@ -5688,7 +5709,11 @@ void
set_init_index (first, last)
tree first, last;
{
- if (tree_int_cst_lt (first, constructor_unfilled_index))
+ if (TREE_CODE (first) != INTEGER_CST)
+ error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ else if (last != 0 && TREE_CODE (last) != INTEGER_CST)
+ error_init ("nonconstant array index in initializer%s", " for `%s'", NULL);
+ else if (tree_int_cst_lt (first, constructor_unfilled_index))
error_init ("duplicate array index in initializer%s", " for `%s'", NULL);
else
{
@@ -5710,7 +5735,7 @@ set_init_index (first, last)
/* Within a struct initializer, specify the next field to be initialized. */
-void
+void
set_init_label (fieldname)
tree fieldname;
{
@@ -5851,11 +5876,13 @@ output_init_element (value, type, field, pending)
if (!duplicate)
{
if (! constructor_incremental)
- constructor_elements
- = tree_cons ((TREE_CODE (constructor_type) != ARRAY_TYPE
- ? field : NULL),
- digest_init (type, value, 0, 0),
- constructor_elements);
+ {
+ if (TREE_CODE (field) == INTEGER_CST)
+ field = copy_node (field);
+ constructor_elements
+ = tree_cons (field, digest_init (type, value, 0, 0),
+ constructor_elements);
+ }
else
{
/* Structure elements may require alignment.
@@ -6031,6 +6058,22 @@ output_pending_init_elements (all)
assemble_zeros (nextpos - TREE_INT_CST_LOW (filled));
}
}
+ else
+ {
+ /* If it's not incremental, just skip over the gap,
+ so that after jumping to retry we will output the next
+ successive element. */
+ if (TREE_CODE (constructor_type) == RECORD_TYPE
+ || TREE_CODE (constructor_type) == UNION_TYPE)
+ constructor_unfilled_fields = next;
+ else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
+ {
+ TREE_INT_CST_LOW (constructor_unfilled_index)
+ = TREE_INT_CST_LOW (next);
+ TREE_INT_CST_HIGH (constructor_unfilled_index)
+ = TREE_INT_CST_HIGH (next);
+ }
+ }
goto retry;
}
@@ -6192,10 +6235,16 @@ process_init_element (value)
RESTORE_SPELLING_DEPTH (constructor_depth);
}
else
- /* If we are doing the bookkeeping for an element that was
- directly output as a constructor,
- we must update constructor_unfilled_fields. */
- constructor_unfilled_fields = 0;
+ /* Do the bookkeeping for an element that was
+ directly output as a constructor. */
+ {
+ TREE_INT_CST_LOW (constructor_bit_index)
+ = TREE_INT_CST_LOW (DECL_SIZE (constructor_fields));
+ TREE_INT_CST_HIGH (constructor_bit_index)
+ = TREE_INT_CST_HIGH (DECL_SIZE (constructor_fields));
+
+ constructor_unfilled_fields = TREE_CHAIN (constructor_fields);
+ }
constructor_fields = 0;
break;