Commit 790e9490 by Richard Stallman

(push_init_level): For braces around scalar, just warn.

(process_init_element): Special handling for {"foo"}.
(struct constructor_stack): New field `replacement_value'.
(push_init_level, really_start_incremental_init): Clear new field.
(pop_init_level): Return the replacement_value if any.
At top level in initializer, output that value,
and set the array size from it.

(digest_init): Delete arg TAIL.  Fix all calls.

(convert_for_assignment): Mismatch in signedness
of pointer targets should not inhibit warnings for const mismatch.

From-SVN: r5042
parent 6d7512e4
...@@ -3899,7 +3899,7 @@ build_c_cast (type, expr) ...@@ -3899,7 +3899,7 @@ build_c_cast (type, expr)
name = ""; name = "";
return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, return digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE,
build_tree_list (field, value)), build_tree_list (field, value)),
NULL_PTR, 0, 0, name); 0, 0);
} }
error ("cast to union type from type not present in union"); error ("cast to union type from type not present in union");
return error_mark_node; return error_mark_node;
...@@ -4273,7 +4273,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) ...@@ -4273,7 +4273,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
Meanwhile, the lhs target must have all the qualifiers of the rhs. */ Meanwhile, the lhs target must have all the qualifiers of the rhs. */
if (TYPE_MAIN_VARIANT (ttl) == void_type_node if (TYPE_MAIN_VARIANT (ttl) == void_type_node
|| TYPE_MAIN_VARIANT (ttr) == void_type_node || TYPE_MAIN_VARIANT (ttr) == void_type_node
|| comp_target_types (type, rhstype)) || comp_target_types (type, rhstype)
|| (unsigned_type (TYPE_MAIN_VARIANT (ttl))
== unsigned_type (TYPE_MAIN_VARIANT (ttr))))
{ {
if (pedantic if (pedantic
&& ((TYPE_MAIN_VARIANT (ttl) == void_type_node && ((TYPE_MAIN_VARIANT (ttl) == void_type_node
...@@ -4292,9 +4294,19 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) ...@@ -4292,9 +4294,19 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
warn_for_assignment ("%s discards `const' from pointer target type", warn_for_assignment ("%s discards `const' from pointer target type",
get_spelling (errtype), funname, parmnum); get_spelling (errtype), funname, parmnum);
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
warn_for_assignment ("%s discards `volatile' from pointer target type", warn_for_assignment ("%s discards `volatile' from pointer target type",
get_spelling (errtype), funname, parmnum); get_spelling (errtype), funname, parmnum);
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (TYPE_MAIN_VARIANT (ttl) == void_type_node
|| TYPE_MAIN_VARIANT (ttr) == void_type_node
|| comp_target_types (type, rhstype))
;
/* If there is a mismatch, do warn. */
else if (pedantic)
warn_for_assignment ("pointer targets in %s differ in signedness",
get_spelling (errtype), funname, parmnum);
} }
else else
{ {
...@@ -4310,13 +4322,6 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) ...@@ -4310,13 +4322,6 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
get_spelling (errtype), funname, parmnum); get_spelling (errtype), funname, parmnum);
} }
} }
else if (unsigned_type (TYPE_MAIN_VARIANT (ttl))
== unsigned_type (TYPE_MAIN_VARIANT (ttr)))
{
if (pedantic)
warn_for_assignment ("pointer targets in %s differ in signedness",
get_spelling (errtype), funname, parmnum);
}
else else
warn_for_assignment ("%s from incompatible pointer type", warn_for_assignment ("%s from incompatible pointer type",
get_spelling (errtype), funname, parmnum); get_spelling (errtype), funname, parmnum);
...@@ -4536,9 +4541,8 @@ store_init_value (decl, init) ...@@ -4536,9 +4541,8 @@ store_init_value (decl, init)
/* Digest the specified initializer into an expression. */ /* Digest the specified initializer into an expression. */
value = digest_init (type, init, NULL_PTR, TREE_STATIC (decl), value = digest_init (type, init, TREE_STATIC (decl),
TREE_STATIC (decl) || pedantic, TREE_STATIC (decl) || pedantic);
IDENTIFIER_POINTER (DECL_NAME (decl)));
/* Store the expression if valid; else report error. */ /* Store the expression if valid; else report error. */
...@@ -4832,8 +4836,8 @@ static tree free_tree_list = NULL_TREE; ...@@ -4832,8 +4836,8 @@ static tree free_tree_list = NULL_TREE;
(That is true for all nested calls to digest_init.) */ (That is true for all nested calls to digest_init.) */
static tree static tree
digest_init (type, init, tail, require_constant, constructor_constant) digest_init (type, init, require_constant, constructor_constant)
tree type, init, *tail; tree type, init;
int require_constant, constructor_constant; int require_constant, constructor_constant;
{ {
enum tree_code code = TREE_CODE (type); enum tree_code code = TREE_CODE (type);
...@@ -5156,6 +5160,9 @@ struct constructor_stack ...@@ -5156,6 +5160,9 @@ struct constructor_stack
int offset; int offset;
tree pending_elts; tree pending_elts;
int depth; int depth;
/* If nonzero, this value should replace the entire
constructor at this level. */
tree replacement_value;
char constant; char constant;
char simple; char simple;
char implicit; char implicit;
...@@ -5319,6 +5326,7 @@ really_start_incremental_init (type) ...@@ -5319,6 +5326,7 @@ really_start_incremental_init (type)
p->erroneous = constructor_erroneous; p->erroneous = constructor_erroneous;
p->pending_elts = constructor_pending_elts; p->pending_elts = constructor_pending_elts;
p->depth = constructor_depth; p->depth = constructor_depth;
p->replacement_value = 0;
p->implicit = 0; p->implicit = 0;
p->incremental = constructor_incremental; p->incremental = constructor_incremental;
p->outer = 0; p->outer = 0;
...@@ -5400,6 +5408,7 @@ push_init_level (implicit) ...@@ -5400,6 +5408,7 @@ push_init_level (implicit)
p->erroneous = constructor_erroneous; p->erroneous = constructor_erroneous;
p->pending_elts = constructor_pending_elts; p->pending_elts = constructor_pending_elts;
p->depth = constructor_depth; p->depth = constructor_depth;
p->replacement_value = 0;
p->implicit = implicit; p->implicit = implicit;
p->incremental = constructor_incremental; p->incremental = constructor_incremental;
p->outer = 0; p->outer = 0;
...@@ -5445,7 +5454,7 @@ push_init_level (implicit) ...@@ -5445,7 +5454,7 @@ push_init_level (implicit)
} }
else else
{ {
error_init ("braces where a scalar is expected%s", " for `%s'", NULL); warning ("braces around scalar initializer");
constructor_fields = constructor_type; constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type; constructor_unfilled_fields = constructor_type;
} }
...@@ -5513,7 +5522,50 @@ pop_init_level (implicit) ...@@ -5513,7 +5522,50 @@ pop_init_level (implicit)
/* Pad out the end of the structure. */ /* Pad out the end of the structure. */
if (! constructor_incremental) if (p->replacement_value)
{
/* If this closes a superfluous brace pair,
just pass out the element between them. */
constructor = p->replacement_value;
/* If this is the top level thing within the initializer,
and it's for a variable, then since we already calle
assemble_variable, we must output the value now. */
if (p->next == 0 && constructor_decl != 0
&& constructor_incremental)
{
constructor = digest_init (constructor_type, constructor,
0, 0);
/* If initializing an array of unknown size,
determine the size now. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& TYPE_DOMAIN (constructor_type) == 0)
{
int failure;
push_obstacks_nochange ();
if (TREE_PERMANENT (constructor_type))
end_temporary_allocation ();
/* We shouldn't have an incomplete array type within
some other type. */
if (constructor_stack->next)
abort ();
failure
= complete_array_type (constructor_type,
constructor, 0);
if (failure)
abort ();
size = int_size_in_bytes (constructor_type);
pop_obstacks ();
}
output_constant (constructor, size);
}
}
else if (! constructor_incremental)
{ {
if (constructor_erroneous) if (constructor_erroneous)
constructor = error_mark_node; constructor = error_mark_node;
...@@ -5750,7 +5802,7 @@ output_init_element (value, type, field, pending) ...@@ -5750,7 +5802,7 @@ output_init_element (value, type, field, pending)
if (! duplicate) if (! duplicate)
constructor_pending_elts constructor_pending_elts
= tree_cons (field, = tree_cons (field,
digest_init (type, value, (tree *)NULL, digest_init (type, value,
require_constant_value, require_constant_value,
require_constant_elements), require_constant_elements),
constructor_pending_elts); constructor_pending_elts);
...@@ -5762,7 +5814,7 @@ output_init_element (value, type, field, pending) ...@@ -5762,7 +5814,7 @@ output_init_element (value, type, field, pending)
if (!duplicate) if (!duplicate)
constructor_pending_elts constructor_pending_elts
= tree_cons (field, = tree_cons (field,
digest_init (type, value, (tree *)NULL, digest_init (type, value,
require_constant_value, require_constant_value,
require_constant_elements), require_constant_elements),
constructor_pending_elts); constructor_pending_elts);
...@@ -5778,7 +5830,7 @@ output_init_element (value, type, field, pending) ...@@ -5778,7 +5830,7 @@ output_init_element (value, type, field, pending)
constructor_elements constructor_elements
= tree_cons ((TREE_CODE (constructor_type) != ARRAY_TYPE = tree_cons ((TREE_CODE (constructor_type) != ARRAY_TYPE
? field : NULL), ? field : NULL),
digest_init (type, value, (tree *)NULL, digest_init (type, value,
require_constant_value, require_constant_value,
require_constant_elements), require_constant_elements),
constructor_elements); constructor_elements);
...@@ -5981,6 +6033,16 @@ process_init_element (value) ...@@ -5981,6 +6033,16 @@ process_init_element (value)
tree orig_value = value; tree orig_value = value;
int string_flag = value != 0 && TREE_CODE (value) == STRING_CST; int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
/* Handle superfluous braces around string cst as in
char x[] = {"foo"}; */
if (string_flag
&& TREE_CODE (constructor_type) == ARRAY_TYPE
&& integer_zerop (constructor_unfilled_index))
{
constructor_stack->replacement_value = value;
return;
}
if (value != 0) if (value != 0)
value = default_conversion (value); value = default_conversion (value);
...@@ -5993,6 +6055,13 @@ process_init_element (value) ...@@ -5993,6 +6055,13 @@ process_init_element (value)
else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
constructor_simple = 0; constructor_simple = 0;
if (constructor_stack->replacement_value != 0)
{
error_init ("excess elements in struct initializer%s",
" after `%s'", NULL_PTR);
return;
}
/* If we've exhausted any levels that didn't have braces, /* If we've exhausted any levels that didn't have braces,
pop them now. */ pop them now. */
while (constructor_stack->implicit) while (constructor_stack->implicit)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment