diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-01 19:40:03 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-01-01 19:40:03 +0000 |
commit | d241bf0d8c67ab7ab3c1963303d9515dbe944c11 (patch) | |
tree | 53fbcd06f068c1f286ce731e58bc68cc5c3d092f | |
parent | f12ce4403edfb51034c4b4c7dc1b9fc723159a32 (diff) | |
download | gcc-d241bf0d8c67ab7ab3c1963303d9515dbe944c11.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142998 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/c-parser.c | 8 | ||||
-rw-r--r-- | gcc/c-tree.h | 5 | ||||
-rw-r--r-- | gcc/c-typeck.c | 107 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr36489.c | 22 |
6 files changed, 119 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bbf1a83cd29..949c8e105e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2009-01-01 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. + 2008-12-31 Uros Bizjak <ubizjak@gmail.com> * sched-deps.c (sched_analyze_2) [UNSPEC_VOLATILE]: Flush pending diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 8c4a96fdee6..99c6c187a1e 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1,6 +1,6 @@ /* Parser for C and Objective-C. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Parser actions based on the old Bison parser; structure somewhat @@ -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, struct c_expr *after) && 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, diff --git a/gcc/c-tree.h b/gcc/c-tree.h index b7430af4b08..395659512ac 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -1,6 +1,7 @@ /* Definitions for C parsing and type checking. Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009 + Free Software Foundation, Inc. This file is part of GCC. @@ -575,7 +576,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); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index c751b4f0e91..35c8d232878 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1,6 +1,6 @@ /* 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. @@ -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; } @@ -5908,10 +5908,15 @@ set_init_label (tree fieldname) /* 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; @@ -5929,10 +5934,13 @@ add_pending_init (tree purpose, tree value) 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 +5960,13 @@ add_pending_init (tree purpose, tree value) 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 +6151,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 +6241,7 @@ set_nonincremental_init_from_string (tree str) } value = build_int_cst_wide (type, val[1], val[0]); - add_pending_init (purpose, value); + add_pending_init (purpose, value, false); } constructor_incremental = 0; @@ -6303,11 +6314,16 @@ find_init_member (tree field) 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; @@ -6386,7 +6402,7 @@ output_init_element (tree value, bool strict_string, tree type, tree field, && 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 +6428,21 @@ output_init_element (tree value, bool strict_string, tree type, tree field, } } - 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 +6513,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 +6566,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)) { @@ -6609,10 +6629,15 @@ output_pending_init_elements (int all) 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; @@ -6653,12 +6678,12 @@ process_init_element (struct c_expr value) 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 +6750,7 @@ process_init_element (struct c_expr value) { 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 +6840,7 @@ process_init_element (struct c_expr value) { 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 +6890,7 @@ process_init_element (struct c_expr value) { 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 +6919,7 @@ process_init_element (struct c_expr value) /* 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 +6944,7 @@ process_init_element (struct c_expr value) { 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 +6960,14 @@ process_init_element (struct c_expr value) 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a5600c25613..001bab0159d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-01-01 Jakub Jelinek <jakub@redhat.com> + + PR c/36489 + * gcc.dg/pr36489.c: New test. + 2008-12-31 Daniel Franke <franke.daniel@gmail.com> * gfortran.dg/mapping_2.f90: Fixed testcase. diff --git a/gcc/testsuite/gcc.dg/pr36489.c b/gcc/testsuite/gcc.dg/pr36489.c new file mode 100644 index 00000000000..5cf221615ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr36489.c @@ -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" } */ |