diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-typeck.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/anon-struct-10.c | 57 |
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); +} |