/* Build expressions with type checking for C compiler.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
static char *print_spelling (char *);
static void warning_init (int, const char *);
static tree digest_init (tree, tree, bool, int);
-static void output_init_element (tree, bool, tree, tree, int);
+static void output_init_element (tree, bool, tree, tree, int, bool);
static void output_pending_init_elements (int);
static int set_designator (int);
static void push_range_stack (tree);
-static void add_pending_init (tree, tree);
+static void add_pending_init (tree, tree, bool);
static void set_nonincremental_init (void);
static void set_nonincremental_init_from_string (tree);
static tree find_init_member (tree);
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& constructor_max_index
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
else
break;
}
/* When we come to an explicit close brace,
pop any inner levels that didn't have explicit braces. */
while (constructor_stack->implicit)
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
gcc_assert (!constructor_range_stack);
}
/* Designator list starts at the level of closest explicit
braces. */
while (constructor_stack->implicit)
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
constructor_designated = 1;
return 0;
}
\f
/* Add a new initializer to the tree of pending initializers. PURPOSE
identifies the initializer, either array index or field in a structure.
- VALUE is the value of that index or field. */
+ VALUE is the value of that index or field.
+
+ IMPLICIT is true if value comes from pop_init_level (1),
+ the new initializer has been merged with the existing one
+ and thus no warnings should be emitted about overriding an
+ existing initializer. */
static void
-add_pending_init (tree purpose, tree value)
+add_pending_init (tree purpose, tree value, bool implicit)
{
struct init_node *p, **q, *r;
q = &p->right;
else
{
- if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
- else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ if (!implicit)
+ {
+ if (TREE_SIDE_EFFECTS (p->value))
+ warning_init (0, "initialized field with side-effects overwritten");
+ else if (warn_override_init)
+ warning_init (OPT_Woverride_init, "initialized field overwritten");
+ }
p->value = value;
return;
}
q = &p->right;
else
{
- if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
- else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ if (!implicit)
+ {
+ if (TREE_SIDE_EFFECTS (p->value))
+ warning_init (0, "initialized field with side-effects overwritten");
+ else if (warn_override_init)
+ warning_init (OPT_Woverride_init, "initialized field overwritten");
+ }
p->value = value;
return;
}
return;
FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
- add_pending_init (index, value);
+ add_pending_init (index, value, false);
constructor_elements = 0;
if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
}
value = build_int_cst_wide (type, val[1], val[0]);
- add_pending_init (purpose, value);
+ add_pending_init (purpose, value, false);
}
constructor_incremental = 0;
PENDING if non-nil means output pending elements that belong
right after this element. (PENDING is normally 1;
- it is 0 while outputting pending elements, to avoid recursion.) */
+ it is 0 while outputting pending elements, to avoid recursion.)
+
+ IMPLICIT is true if value comes from pop_init_level (1),
+ the new initializer has been merged with the existing one
+ and thus no warnings should be emitted about overriding an
+ existing initializer. */
static void
output_init_element (tree value, bool strict_string, tree type, tree field,
- int pending)
+ int pending, bool implicit)
{
constructor_elt *celt;
&& tree_int_cst_lt (field, constructor_unfilled_index))
set_nonincremental_init ();
- add_pending_init (field, value);
+ add_pending_init (field, value, implicit);
return;
}
else if (TREE_CODE (constructor_type) == RECORD_TYPE
}
}
- add_pending_init (field, value);
+ add_pending_init (field, value, implicit);
return;
}
else if (TREE_CODE (constructor_type) == UNION_TYPE
&& !VEC_empty (constructor_elt, constructor_elements))
{
- if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
- constructor_elements)->value))
- warning_init (0, "initialized field with side-effects overwritten");
- else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ if (!implicit)
+ {
+ if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
+ constructor_elements)->value))
+ warning_init (0,
+ "initialized field with side-effects overwritten");
+ else if (warn_override_init)
+ warning_init (OPT_Woverride_init, "initialized field overwritten");
+ }
/* We can have just one union field set. */
constructor_elements = 0;
constructor_unfilled_index))
output_init_element (elt->value, true,
TREE_TYPE (constructor_type),
- constructor_unfilled_index, 0);
+ constructor_unfilled_index, 0, false);
else if (tree_int_cst_lt (constructor_unfilled_index,
elt->purpose))
{
{
constructor_unfilled_fields = elt->purpose;
output_init_element (elt->value, true, TREE_TYPE (elt->purpose),
- elt->purpose, 0);
+ elt->purpose, 0, false);
}
else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos))
{
to handle a partly-braced initializer.
Once this has found the correct level for the new element,
- it calls output_init_element. */
+ it calls output_init_element.
+
+ IMPLICIT is true if value comes from pop_init_level (1),
+ the new initializer has been merged with the existing one
+ and thus no warnings should be emitted about overriding an
+ existing initializer. */
void
-process_init_element (struct c_expr value)
+process_init_element (struct c_expr value, bool implicit)
{
tree orig_value = value.value;
int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST;
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& (constructor_max_index == 0
|| tree_int_cst_lt (constructor_max_index,
constructor_index)))
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
else
break;
}
{
push_member_name (constructor_fields);
output_init_element (value.value, strict_string,
- fieldtype, constructor_fields, 1);
+ fieldtype, constructor_fields, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
else
{
push_member_name (constructor_fields);
output_init_element (value.value, strict_string,
- fieldtype, constructor_fields, 1);
+ fieldtype, constructor_fields, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
else
{
push_array_bounds (tree_low_cst (constructor_index, 1));
output_init_element (value.value, strict_string,
- elttype, constructor_index, 1);
+ elttype, constructor_index, 1, implicit);
RESTORE_SPELLING_DEPTH (constructor_depth);
}
/* Now output the actual element. */
if (value.value)
output_init_element (value.value, strict_string,
- elttype, constructor_index, 1);
+ elttype, constructor_index, 1, implicit);
constructor_index
= size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
{
if (value.value)
output_init_element (value.value, strict_string,
- constructor_type, NULL_TREE, 1);
+ constructor_type, NULL_TREE, 1, implicit);
constructor_fields = 0;
}
while (constructor_stack != range_stack->stack)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
}
for (p = range_stack;
!p->range_end || tree_int_cst_equal (p->index, p->range_end);
p = p->prev)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1));
+ process_init_element (pop_init_level (1), true);
}
p->index = size_binop (PLUS_EXPR, p->index, bitsize_one_node);