]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/36489 (Warning "initialized field overwritten" wrongly triggers with multidim...
authorJakub Jelinek <jakub@redhat.com>
Thu, 1 Jan 2009 19:40:03 +0000 (20:40 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 1 Jan 2009 19:40:03 +0000 (20:40 +0100)
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.

From-SVN: r142998

gcc/ChangeLog
gcc/c-parser.c
gcc/c-tree.h
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr36489.c [new file with mode: 0644]

index bbf1a83cd29ad8d98e3592d5a980fef16264cb85..949c8e105e647cd4083b73625b69c574ded5981e 100644 (file)
@@ -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
index 8c4a96fdee671b5f08547ac3a25fbce11df6e9fd..99c6c187a1e6060635e8a8b9e48c442872957f8e 100644 (file)
@@ -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,
index b7430af4b08f8fc011dafe3752b0f8beebcfc858..395659512ac2759274d3d5623e78bdb7cac9bbcc 100644 (file)
@@ -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);
index c751b4f0e917d67b025bc0fefef4b67b91a7cc7b..35c8d232878353824b00d6b8faf2f6ba3fcd0459 100644 (file)
@@ -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)
 \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;
 
@@ -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);
index a5600c256139c059752896e0b9208d33e12509cd..001bab0159d03efc755c8134a156a1e476b1ee8f 100644 (file)
@@ -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 (file)
index 0000000..5cf2216
--- /dev/null
@@ -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" } */