OSDN Git Service

PR c/10676
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 May 2010 20:39:39 +0000 (20:39 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 May 2010 20:39:39 +0000 (20:39 +0000)
* c-typeck.c (lookup_field): Take a type directly.  Update
recursive calls.
(build_component_ref): Update call to lookup_field.
(set_init_label): Use lookup_field to find initialized field.
Handle returned list of fields like a sequence of designators.

testsuite:
* gcc.dg/anon-struct-10.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159206 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/anon-struct-10.c [new file with mode: 0644]

index 6551ac0..5f79292 100644 (file)
@@ -1,3 +1,12 @@
+2010-05-09  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/10676
+       * c-typeck.c (lookup_field): Take a type directly.  Update
+       recursive calls.
+       (build_component_ref): Update call to lookup_field.
+       (set_init_label): Use lookup_field to find initialized field.
+       Handle returned list of fields like a sequence of designators.
+
 2010-05-09  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/44024
index 2f66d6a..1bac4fd 100644 (file)
@@ -1953,7 +1953,7 @@ default_conversion (tree exp)
   return exp;
 }
 \f
-/* Look up COMPONENT in a structure or union DECL.
+/* Look up COMPONENT in a structure or union TYPE.
 
    If the component name is not found, returns NULL_TREE.  Otherwise,
    the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL
@@ -1963,9 +1963,8 @@ default_conversion (tree exp)
    unions, the list steps down the chain to the component.  */
 
 static tree
-lookup_field (tree decl, tree component)
+lookup_field (tree type, tree component)
 {
-  tree type = TREE_TYPE (decl);
   tree field;
 
   /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers
@@ -1995,7 +1994,7 @@ lookup_field (tree decl, tree component)
                  if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
                      || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
                    {
-                     tree anon = lookup_field (field, component);
+                     tree anon = lookup_field (TREE_TYPE (field), component);
 
                      if (anon)
                        return tree_cons (NULL_TREE, field, anon);
@@ -2031,7 +2030,7 @@ lookup_field (tree decl, tree component)
              && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
                  || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
            {
-             tree anon = lookup_field (field, component);
+             tree anon = lookup_field (TREE_TYPE (field), component);
 
              if (anon)
                return tree_cons (NULL_TREE, field, anon);
@@ -2074,7 +2073,7 @@ build_component_ref (location_t loc, tree datum, tree component)
          return error_mark_node;
        }
 
-      field = lookup_field (datum, component);
+      field = lookup_field (type, component);
 
       if (!field)
        {
@@ -6983,7 +6982,7 @@ set_init_index (tree first, tree last,
 void
 set_init_label (tree fieldname, struct obstack * braced_init_obstack)
 {
-  tree tail;
+  tree field;
 
   if (set_designator (0, braced_init_obstack))
     return;
@@ -6997,23 +6996,26 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack)
       return;
     }
 
-  for (tail = TYPE_FIELDS (constructor_type); tail;
-       tail = TREE_CHAIN (tail))
-    {
-      if (DECL_NAME (tail) == fieldname)
-       break;
-    }
+  field = lookup_field (constructor_type, fieldname);
 
-  if (tail == 0)
+  if (field == 0)
     error ("unknown field %qE specified in initializer", fieldname);
   else
-    {
-      constructor_fields = tail;
-      designator_depth++;
-      designator_erroneous = 0;
-      if (constructor_range_stack)
-       push_range_stack (NULL_TREE, braced_init_obstack);
-    }
+    do
+      {
+       constructor_fields = TREE_VALUE (field);
+       designator_depth++;
+       designator_erroneous = 0;
+       if (constructor_range_stack)
+         push_range_stack (NULL_TREE, braced_init_obstack);
+       field = TREE_CHAIN (field);
+       if (field)
+         {
+           if (set_designator (0, braced_init_obstack))
+             return;
+         }
+      }
+    while (field != NULL_TREE);
 }
 \f
 /* Add a new initializer to the tree of pending initializers.  PURPOSE
index f0a10bb..696d4cc 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-09  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/10676
+       * gcc.dg/anon-struct-10.c: New test.
+
 2010-05-09  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/44024
diff --git a/gcc/testsuite/gcc.dg/anon-struct-10.c b/gcc/testsuite/gcc.dg/anon-struct-10.c
new file mode 100644 (file)
index 0000000..e212317
--- /dev/null
@@ -0,0 +1,57 @@
+/* Test for designated initializers for anonymous structures and
+   unions.  PR 10676.  */
+/* { dg-do run } */
+/* { dg-options "" } */
+
+extern void abort (void);
+extern void exit (int);
+
+struct s
+{
+  int a;
+  struct
+  {
+    int b;
+    int c;
+  };
+  union
+  {
+    int d;
+    struct
+    {
+      int e;
+    };
+  };
+  struct
+  {
+    struct
+    {
+      struct
+      {
+       int f;
+      };
+    };
+  };
+};
+
+struct s x =
+  {
+    .e = 5,
+    .b = 4,
+    .a = 3,
+    .f = 7,
+    .c = 9
+  };
+
+int
+main (void)
+{
+  if (x.a != 3
+      || x.b != 4
+      || x.c != 9
+      || x.d != 5
+      || x.e != 5
+      || x.f != 7)
+    abort ();
+  exit (0);
+}