tree truthvalue_conversion ();
void incomplete_type_error ();
void readonly_warning ();
+static tree internal_build_compound_expr ();
+
\f
/* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) */
else return t2;
case POINTER_TYPE:
-#if 0
/* For two pointers, do this recursively on the target type,
and combine the qualifiers of the two types' targets. */
+ /* This code was turned off; I don't know why.
+ But ANSI C specifies doing this with the qualifiers.
+ So I turned it on again. */
{
tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)),
TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
= TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
return build_pointer_type (c_build_type_variant (target, constp, volatilep));
}
-#endif
+#if 0
return build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
+#endif
case ARRAY_TYPE:
{
tree type;
{
enum tree_code code = TREE_CODE (type);
+ tree t;
if (code == FUNCTION_TYPE)
{
}
/* Convert in case a char is more than one unit. */
- return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (TYPE_PRECISION (char_type_node)));
+ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+ size_int (TYPE_PRECISION (char_type_node)));
+ /* size_binop does not put the constant in range, so do it now. */
+ if (TREE_CODE (t) == INTEGER_CST)
+ force_fit_type (t);
+ return t;
}
tree
tree type;
{
enum tree_code code = TREE_CODE (type);
+ tree t;
if (code == FUNCTION_TYPE
|| code == VOID_TYPE
return size_int (0);
/* Convert in case a char is more than one unit. */
- return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
- size_int (TYPE_PRECISION (char_type_node)));
+ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+ size_int (TYPE_PRECISION (char_type_node)));
+ force_fit_type (t);
+ return t;
}
/* Compute the size to increment a pointer by. */
tree type;
{
enum tree_code code = TREE_CODE (type);
+ tree t;
if (code == FUNCTION_TYPE)
return size_int (1);
}
/* Convert in case a char is more than one unit. */
- return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+ t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
size_int (BITS_PER_UNIT));
+ force_fit_type (t);
+ return t;
}
/* Implement the __alignof keyword: Return the minimum required
return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
}
-
-/* Print a warning if a constant expression had overflow in folding.
- This doesn't really work--it is waiting for changes in fold. */
-
-void
-constant_expression_warning (value)
- tree value;
-{
- if (TREE_CODE (value) == NON_LVALUE_EXPR && TREE_CONSTANT_OVERFLOW (value))
- pedwarn ("overflow in constant expression");
-}
\f
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
"aligned" __attribute__ specification). */
+
tree
c_alignof_expr (expr)
tree expr;
/* A de-reference of a pointer to const is not a const. It is valid
to change it via some other pointer. */
TREE_READONLY (ref) = TYPE_READONLY (t);
- TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
- TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
+ TREE_SIDE_EFFECTS (ref)
+ = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
+ TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t) || flag_volatile;
return ref;
}
else if (TREE_CODE (pointer) != ERROR_MARK)
#define T_LD &long_double_type_node
#define T_C &char_type_node
#define T_V &void_type_node
+#define T_W &wchar_type_node
typedef struct
{
{ "oxX", 0, T_UI, T_UI, T_UL, NULL, "-wp0#" },
{ "u", 0, T_UI, T_UI, T_UL, NULL, "-wp0" },
{ "feEgG", 0, T_D, NULL, NULL, T_LD, "-wp0 +#" },
- { "c", 0, T_I, NULL, NULL, NULL, "-w" },
- { "s", 1, T_C, NULL, NULL, NULL, "-wp" },
+ { "c", 0, T_I, NULL, T_W, NULL, "-w" },
+ { "C", 0, T_W, NULL, NULL, NULL, "-w" },
+ { "s", 1, T_C, NULL, T_W, NULL, "-wp" },
+ { "S", 1, T_W, NULL, NULL, NULL, "-wp" },
{ "p", 1, T_V, NULL, NULL, NULL, "-" },
{ "n", 1, T_I, T_S, T_L, NULL, "" },
{ NULL }
{ "di", 1, T_I, T_S, T_L, NULL, "*" },
{ "ouxX", 1, T_UI, T_US, T_UL, NULL, "*" },
{ "efgEG", 1, T_F, NULL, T_D, T_LD, "*" },
- { "s[c", 1, T_C, NULL, NULL, NULL, "*" },
+ { "sc", 1, T_C, NULL, T_W, NULL, "*" },
+ { "[", 1, T_C, NULL, NULL, NULL, "*" },
+ { "C", 1, T_W, NULL, NULL, NULL, "*" },
+ { "S", 1, T_W, NULL, NULL, NULL, "*" },
{ "p", 2, T_V, NULL, NULL, NULL, "*" },
{ "n", 1, T_I, T_S, T_L, NULL, "" },
{ NULL }
if (*format_chars == '.')
{
precise = TRUE;
- /* "For d, i, o, u, x, and X conversions,
- if a precision is specified, the 0 flag will be ignored.
- For other conversions, the behavior is undefined." */
- if (index (flag_chars, '0') != 0)
- warning ("precision and `0' flag both used in one %%-sequence");
++format_chars;
if (*format_chars != '*' && !ISDIGIT (*format_chars))
warning ("`.' not followed by `*' or digit in format");
}
if (fci->format_chars == 0)
{
- if (format_char >= 040 && format_char <= 0177)
+ if (format_char >= 040 && format_char < 0177)
sprintf (message,
"unknown conversion type character `%c' in format",
format_char);
warning (message);
}
}
+ if (precise && index (flag_chars, '0') != 0
+ && (format_char == 'd' || format_char == 'i'
+ || format_char == 'o' || format_char == 'u'
+ || format_char == 'x' || format_char == 'x'))
+ {
+ sprintf (message,
+ "precision and `0' flag not both allowed with `%c' format",
+ format_char);
+ warning (message);
+ }
switch (length_char)
{
default: wanted_type = fci->nolen ? *(fci->nolen) : 0; break;
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE || code0 == REAL_TYPE)
&& (code1 == INTEGER_TYPE || code1 == POINTER_TYPE || code1 == REAL_TYPE))
{
{
if (TREE_CODE (op1) == INTEGER_CST)
{
- if (TREE_INT_CST_LOW (op1) > 0)
- short_shift = 1;
- else if (TREE_INT_CST_LOW (op1) < 0)
- warning ("shift count is negative");
- if (TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))
- warning ("shift count >= width of type");
+ if (tree_int_cst_lt (op1, integer_zero_node))
+ warning ("right shift count is negative");
+ else
+ {
+ if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1))
+ short_shift = 1;
+ if (TREE_INT_CST_HIGH (op1) != 0
+ || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
+ >= TYPE_PRECISION (type0)))
+ warning ("right shift count >= width of type");
+ }
}
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
case LSHIFT_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
- if (TREE_CODE (op1) == INTEGER_CST
- && TREE_INT_CST_LOW (op1) < 0)
- warning ("shift count is negative");
- if (TREE_CODE (op1) == INTEGER_CST
- && TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))
- warning ("shift count >= width of type");
+ if (TREE_CODE (op1) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (op1, integer_zero_node))
+ warning ("left shift count is negative");
+ else if (TREE_INT_CST_HIGH (op1) != 0
+ || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
+ >= TYPE_PRECISION (type0)))
+ warning ("left shift count >= width of type");
+ }
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
result_type = type0;
case LROTATE_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
- if (TREE_CODE (op1) == INTEGER_CST
- && TREE_INT_CST_LOW (op1) < 0)
- warning ("shift count is negative");
- if (TREE_CODE (op1) == INTEGER_CST
- && TREE_INT_CST_LOW (op1) >= TYPE_PRECISION (type0))
- warning ("shift count >= width of type");
+ if (TREE_CODE (op1) == INTEGER_CST)
+ {
+ if (tree_int_cst_lt (op1, integer_zero_node))
+ warning ("shift count is negative");
+ else if (TREE_INT_CST_HIGH (op1) != 0
+ || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1)
+ >= TYPE_PRECISION (type0)))
+ warning ("shift count >= width of type");
+ }
/* Use the type of the value to be shifted.
This is what most traditional C compilers do. */
result_type = type0;
case FIX_FLOOR_EXPR:
case FIX_ROUND_EXPR:
case FIX_CEIL_EXPR:
+ pedantic_lvalue_warning (CONVERT_EXPR);
/* If the real type has the same machine representation
as the type it is cast to, we can make better output
by adding directly to the inside of the cast. */
else
{
tree incremented, modify, value;
- pedantic_lvalue_warning (CONVERT_EXPR);
arg = stabilize_reference (arg);
if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
value = arg;
addr = build1 (code, argtype, arg);
/* Address of a static or external variable or
- function counts as a constant */
- TREE_CONSTANT (addr) = staticp (arg);
+ file-scope function counts as a constant. */
+ if (staticp (arg)
+ && ! (TREE_CODE (arg) == FUNCTION_DECL
+ && DECL_CONTEXT (arg) != 0))
+ TREE_CONSTANT (addr) = 1;
return addr;
}
}
/* Merge const and volatile flags of the incoming types. */
result_type
= build_type_variant (result_type,
- TYPE_READONLY (op1) || TYPE_READONLY (op2),
- TYPE_VOLATILE (op1) || TYPE_VOLATILE (op2));
+ TREE_READONLY (op1) || TREE_READONLY (op2),
+ TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
if (result_type != TREE_TYPE (op1))
op1 = convert (result_type, op1);
build_compound_expr (list)
tree list;
{
+ internal_build_compound_expr (list, TRUE);
+}
+
+static tree
+internal_build_compound_expr (list, first_p)
+ tree list;
+ int first_p;
+{
register tree rest;
if (TREE_CHAIN (list) == 0)
list = TREE_OPERAND (list, 0);
#endif
- return TREE_VALUE (list);
+ /* Don't let (0, 0) be null pointer constant. */
+ if (!first_p && integer_zerop (TREE_VALUE (list)))
+ return non_lvalue (TREE_VALUE (list));
+ return TREE_VALUE (list);
}
if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0)
= default_conversion (TREE_VALUE (TREE_CHAIN (list)));
}
- rest = build_compound_expr (TREE_CHAIN (list));
+ rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
return rest;
if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE
- && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
+ && TYPE_PRECISION (type) != TYPE_PRECISION (otype)
+ && !TREE_CONSTANT (value))
warning ("cast from pointer to integer of different size");
if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == INTEGER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype)
+#if 0
/* Don't warn about converting 0 to pointer,
provided the 0 was explicit--not cast or made by folding. */
- && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value)))
+ && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))
+#endif
+ /* Don't warn about converting any constant. */
+ && !TREE_CONSTANT (value))
warning ("cast to pointer from integer of different size");
value = convert (type, value);
arithmetic-combinations of integers. */
static tree
-initializer_constant_valid_p (value)
+initializer_constant_valid_p (value, endtype)
tree value;
+ tree endtype;
{
switch (TREE_CODE (value))
{
return TREE_OPERAND (value, 0);
case NON_LVALUE_EXPR:
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
case CONVERT_EXPR:
case NOP_EXPR:
/* Allow conversions between pointer types. */
if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
/* Allow conversions between real types. */
if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
/* Allow length-preserving conversions between integer types. */
if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
&& tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)),
TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
/* Allow conversions between integer types only if explicit value. */
if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
{
- tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+ endtype);
if (inner == null_pointer_node)
return null_pointer_node;
return 0;
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
&& tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (value)),
TYPE_SIZE (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0),
+ endtype);
/* Allow conversions to union types if the value inside is okay. */
if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0));
+ return initializer_constant_valid_p (TREE_OPERAND (value, 0),
+ endtype);
return 0;
case PLUS_EXPR:
+ if (TREE_CODE (endtype) == INTEGER_TYPE
+ && TYPE_PRECISION (endtype) < POINTER_SIZE)
+ return 0;
{
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0));
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1));
+ tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+ endtype);
+ tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
+ endtype);
/* If either term is absolute, use the other terms relocation. */
if (valid0 == null_pointer_node)
return valid1;
}
case MINUS_EXPR:
+ if (TREE_CODE (endtype) == INTEGER_TYPE
+ && TYPE_PRECISION (endtype) < POINTER_SIZE)
+ return 0;
{
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0));
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1));
+ tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+ endtype);
+ tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
+ endtype);
/* Win if second argument is absolute. */
if (valid1 == null_pointer_node)
return valid0;
value = error_mark_node;
}
else if (TREE_STATIC (decl)
- && initializer_constant_valid_p (value) == 0)
+ && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
{
error ("initializer for static variable uses complicated arithmetic");
value = error_mark_node;
" for `%s'", ofwhat);
inside_init = error_mark_node;
}
- else if (require_constant && initializer_constant_valid_p (inside_init) == 0)
+ else if (require_constant
+ && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
error_init ("initializer element%s is not computable at load time",
" for `%s'", ofwhat);
" for `%s'", ofwhat);
element = error_mark_node;
}
- else if (require_constant && initializer_constant_valid_p (element) == 0)
+ else if (require_constant
+ && initializer_constant_valid_p (element, TREE_TYPE (element)) == 0)
{
error_init ("initializer element%s is not computable at load time",
" for `%s'", ofwhat);
" for `%s'", ofwhat);
inside_init = error_mark_node;
}
- else if (require_constant && initializer_constant_valid_p (inside_init) == 0)
+ else if (require_constant
+ && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
{
error_init ("initializer element%s is not computable at load time",
" for `%s'", ofwhat);
tree min_index, max_index, current_index, members_index;
tree bound_type;
tree one;
+ /* These are non-zero only within a range initializer. */
+ tree start_index = 0, end_index = 0;
+ /* Within a range, this is the value for the elts in the range. */
+ tree range_val = 0;
/* If we have array bounds, set our bounds from that. Otherwise,
we have a lower bound of zero and an unknown upper bound. Also
/* Don't leave the loop based on index if the next item has an explicit
index value that will override it. */
- for (current_index = min_index; tail != 0;
+ for (current_index = min_index; tail != 0 || end_index;
current_index = fold (build (PLUS_EXPR, bound_type,
current_index, one)))
{
- register tree next1;
+ register tree next1 = 0;
+
+ /* Handle the case where we are inside of a range.
+ current_index increments through the range,
+ so just keep reusing the same element of TAIL
+ until the end of the range. */
+ if (end_index != 0)
+ {
+ next1 = range_val;
+ if (!tree_int_cst_lt (current_index, end_index))
+ end_index = 0;
+ }
/* If this element specifies an index,
move to that index before storing it in the new list. */
- if (TREE_PURPOSE (tail) != 0)
+ else if (TREE_PURPOSE (tail) != 0)
{
int win = 0;
tree index = TREE_PURPOSE (tail);
- if (index && TREE_CODE (index) == NON_LVALUE_EXPR)
+ if (index && (TREE_CODE (index) == NON_LVALUE_EXPR
+ || TREE_CODE (index) == NOP_EXPR))
index = TREE_OPERAND (index, 0);
- if (TREE_CODE (index) == IDENTIFIER_NODE)
+ /* Begin a range. */
+ if (TREE_CODE (index) == TREE_LIST)
+ {
+ start_index = TREE_PURPOSE (index);
+ end_index = TREE_PURPOSE (TREE_CHAIN (index));
+
+ /* Expose constants. It Doesn't matter if we change
+ the mode.*/
+ if (end_index
+ && (TREE_CODE (end_index) == NON_LVALUE_EXPR
+ || TREE_CODE (end_index) == NOP_EXPR))
+ end_index = TREE_OPERAND (end_index, 0);
+ if (start_index
+ && (TREE_CODE (start_index) == NON_LVALUE_EXPR
+ || TREE_CODE (start_index) == NOP_EXPR))
+ start_index = TREE_OPERAND (start_index, 0);
+
+ if ((TREE_CODE (start_index) == IDENTIFIER_NODE)
+ || (TREE_CODE (end_index) == IDENTIFIER_NODE))
+ error ("field name used as index in array initializer");
+ else if ((TREE_CODE (start_index) != INTEGER_CST)
+ || (TREE_CODE (end_index) != INTEGER_CST))
+ error ("non-constant array index in initializer");
+ else if (tree_int_cst_lt (start_index, min_index)
+ || (max_index && tree_int_cst_lt (max_index, start_index))
+ || tree_int_cst_lt (end_index, min_index)
+ || (max_index && tree_int_cst_lt (max_index, end_index)))
+ error ("array index out of range in initializer");
+ else if (tree_int_cst_lt (end_index, start_index))
+ {
+ /* If the range is empty, don't initialize any elements,
+ but do reset current_index for the next initializer
+ element. */
+ warning ("empty array initializer range");
+ tail = TREE_CHAIN (tail);
+ current_index = end_index;
+ continue;
+ }
+ else
+ {
+ current_index = start_index;
+ win = 1;
+ /* See if the first element is also the last. */
+ if (!tree_int_cst_lt (current_index, end_index))
+ end_index = 0;
+ }
+ }
+ else if (TREE_CODE (index) == IDENTIFIER_NODE)
error ("field name used as index in array initializer");
else if (TREE_CODE (index) != INTEGER_CST)
error ("non-constant array index in initializer");
current_index = index, win = 1;
if (!win)
- TREE_VALUE (tail) = error_mark_node;
+ {
+ /* If there was an error, end the current range. */
+ end_index = 0;
+ TREE_VALUE (tail) = error_mark_node;
+ }
}
if (max_index && tree_int_cst_lt (max_index, current_index))
break; /* Stop if we've indeed run out of elements. */
/* Now digest the value specified. */
- if (TREE_VALUE (tail) != 0)
+ if (next1 != 0)
+ ;
+ else if (TREE_VALUE (tail) != 0)
{
tree tail1 = tail;
tail = TREE_CHAIN (tail);
}
+ if (end_index != 0)
+ range_val = next1;
+
if (next1 == error_mark_node)
erroneous = 1;
else if (!TREE_CONSTANT (next1))
allconstant = 0;
- else if (initializer_constant_valid_p (next1) == 0)
+ else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
allsimple = 0;
/* Now store NEXT1 in the list, I elements from the *end*.
erroneous = 1;
else if (!TREE_CONSTANT (next1))
allconstant = 0;
- else if (initializer_constant_valid_p (next1) == 0)
+ else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
allsimple = 0;
/* Now store NEXT1 in the list, I elements from the *end*.
/* For a union, get the initializer for 1 fld. */
+ if (tail == 0)
+ {
+ error ("empty initializer for union");
+ tail = build_tree_list (0, 0);
+ }
+
/* If this element specifies a field, initialize via that field. */
if (TREE_PURPOSE (tail) != 0)
{
erroneous = 1;
else if (!TREE_CONSTANT (next1))
allconstant = 0;
- else if (initializer_constant_valid_p (next1) == 0)
+ else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0)
allsimple = 0;
members = tree_cons (field, next1, members);
}