aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-typeck.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/anon-struct-10.c57
4 files changed, 94 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6551ac0..5f79292 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 2f66d6a..1bac4fd 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1953,7 +1953,7 @@ default_conversion (tree exp)
return exp;
}
-/* 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);
}
/* Add a new initializer to the tree of pending initializers. PURPOSE
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f0a10bb..696d4cc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..e212317
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/anon-struct-10.c
@@ -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);
+}