This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix C -Woverride-init warning (PR c/36489)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 30 Dec 2008 01:33:25 +0100
- Subject: [PATCH] Fix C -Woverride-init warning (PR c/36489)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
add_pending_init and output_init_element warn with -Woverride-init
(or with initializers with side-effects) even for deeper designated
initializers when no overriding happens. The following patch
fixes it by not warning when process_init_element pop_init_level(1),
where initializers are merged together. We only want to warn at the
lowest level, as shown on the testcase.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2008-12-30 Jakub Jelinek <jakub@redhat.com>
PR c/36489
* c-typeck.c (add_pending_init): Add IMPLICIT argument. Only
warn about overwriting initializer with side-effects or
-Woverride-init if !IMPLICIT.
(output_init_element): Likewise. Pass IMPLICIT down to
add_pending_init.
(process_init_element): Add IMPLICIT argument. Pass it down
to output_init_element.
(push_init_element, pop_init_level, set_designator): Adjust
process_init_element callers.
(set_nonincremental_init, set_nonincremental_init_from_string):
Adjust add_pending_init callers.
(output_pending_init_elements): Adjust output_init_element callers.
* c-tree.h (process_init_element): Adjust prototype.
* c-parser.c (c_parser_initelt, c_parser_initval): Adjust
process_init_element callers.
* gcc.dg/pr36489.c: New test.
--- gcc/c-typeck.c.jj 2008-12-11 09:46:57.000000000 +0100
+++ gcc/c-typeck.c 2008-12-29 23:59:02.000000000 +0100
@@ -92,11 +92,11 @@ static int spelling_length (void);
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);
@@ -5389,12 +5389,12 @@ push_init_level (int implicit)
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;
}
@@ -5588,7 +5588,7 @@ pop_init_level (int implicit)
/* 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);
}
@@ -5747,7 +5747,7 @@ set_designator (int array)
/* 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;
}
@@ -5911,7 +5911,7 @@ set_init_label (tree fieldname)
VALUE is the value of that index or field. */
static void
-add_pending_init (tree purpose, tree value)
+add_pending_init (tree purpose, tree value, bool implicit)
{
struct init_node *p, **q, *r;
@@ -5929,10 +5929,13 @@ add_pending_init (tree purpose, tree val
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;
}
@@ -5952,10 +5955,13 @@ add_pending_init (tree purpose, tree val
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;
}
@@ -6140,7 +6146,7 @@ set_nonincremental_init (void)
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)
{
@@ -6230,7 +6236,7 @@ set_nonincremental_init_from_string (tre
}
value = build_int_cst_wide (type, val[1], val[0]);
- add_pending_init (purpose, value);
+ add_pending_init (purpose, value, false);
}
constructor_incremental = 0;
@@ -6307,7 +6313,7 @@ find_init_member (tree field)
static void
output_init_element (tree value, bool strict_string, tree type, tree field,
- int pending)
+ int pending, bool implicit)
{
constructor_elt *celt;
@@ -6386,7 +6392,7 @@ output_init_element (tree value, bool st
&& 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
@@ -6412,17 +6418,21 @@ output_init_element (tree value, bool st
}
}
- 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;
@@ -6493,7 +6503,7 @@ output_pending_init_elements (int all)
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))
{
@@ -6546,7 +6556,7 @@ output_pending_init_elements (int all)
{
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))
{
@@ -6612,7 +6622,7 @@ output_pending_init_elements (int all)
it calls output_init_element. */
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;
@@ -6653,12 +6663,12 @@ process_init_element (struct c_expr valu
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;
}
@@ -6725,7 +6735,7 @@ process_init_element (struct c_expr valu
{
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
@@ -6815,7 +6825,7 @@ process_init_element (struct c_expr valu
{
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
@@ -6865,7 +6875,7 @@ process_init_element (struct c_expr valu
{
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);
}
@@ -6894,7 +6904,7 @@ process_init_element (struct c_expr valu
/* 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);
@@ -6919,7 +6929,7 @@ process_init_element (struct c_expr valu
{
if (value.value)
output_init_element (value.value, strict_string,
- constructor_type, NULL_TREE, 1);
+ constructor_type, NULL_TREE, 1, implicit);
constructor_fields = 0;
}
@@ -6935,14 +6945,14 @@ process_init_element (struct c_expr valu
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);
--- gcc/c-tree.h.jj 2008-10-27 08:26:46.000000000 +0100
+++ gcc/c-tree.h 2008-12-29 16:35:17.000000000 +0100
@@ -575,7 +575,7 @@ extern void push_init_level (int);
extern struct c_expr pop_init_level (int);
extern void set_init_index (tree, tree);
extern void set_init_label (tree);
-extern void process_init_element (struct c_expr);
+extern void process_init_element (struct c_expr, bool);
extern tree build_compound_literal (tree, tree);
extern tree c_start_case (tree);
extern void c_finish_case (tree);
--- gcc/c-parser.c.jj 2008-12-06 09:56:49.000000000 +0100
+++ gcc/c-parser.c 2008-12-29 16:35:30.000000000 +0100
@@ -3090,7 +3090,7 @@ c_parser_initelt (c_parser *parser)
init.original_code = ERROR_MARK;
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init);
+ process_init_element (init, false);
return;
}
}
@@ -3213,7 +3213,7 @@ c_parser_initelt (c_parser *parser)
init.original_code = ERROR_MARK;
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init);
+ process_init_element (init, false);
return;
}
}
@@ -3243,7 +3243,7 @@ c_parser_initval (c_parser *parser, stru
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
init = default_function_array_conversion (init);
}
- process_init_element (init);
+ process_init_element (init, false);
}
/* Parse a compound statement (possibly a function body) (C90 6.6.2,
--- gcc/testsuite/gcc.dg/pr36489.c.jj 2008-12-29 16:45:41.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr36489.c 2008-12-29 23:56:38.000000000 +0100
@@ -0,0 +1,22 @@
+/* PR c/36489 */
+/* { dg-do compile } */
+/* { dg-options "-Woverride-init" } */
+
+struct A { int a; int b[3]; };
+union B { int a; int b[3]; };
+int t1[10][10]
+ = { [1][2] = 11, [1][3] = 12 };
+int t2[10][10]
+ = { [1][2] = 11, [1] = { [3] = 12 } }; /* { dg-warning "initializ" } */
+int t3[10][10]
+ = { [1][2] = 11, [1][2] = 12 }; /* { dg-warning "initializ" } */
+struct A t4[2]
+ = { [0].b[0] = 1, [0].b[1] = 2, [0].b[2] = 3 };
+struct A t5[2]
+ = { [0].b[0] = 1, [0].b[1] = 2, [0].b = { 3 } }; /* { dg-warning "initializ" } */
+union B t6
+ = { .b[0] = 1, .b[1] = 2, .b[2] = 3 };
+union B t7
+ = { .b[0] = 1, .b[1] = 2, .b = { 2 } }; /* { dg-warning "initializ" } */
+union B t8
+ = { .b[0] = 1, .b[1] = 2, .b[1] = 3 }; /* { dg-warning "initializ" } */
Jakub