diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-typeck.c | 48 |
2 files changed, 32 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7dac519..e500186 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-11-26 Alexandre Oliva <aoliva@redhat.com> + + PR c/27898 + * c-typeck.c (tagged_types_tu_compatible_p): Enable exact + matches between anonymous union fields. + 2007-11-26 Alexandre Oliva <aoliva@redhat.com>, Jan Hubicka <jh@suse.cz> * tree-ssa-live.c (remove_unused_scope_block_p): Drop diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index eee5789..6d94cab 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1233,11 +1233,12 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2) { int result; - - if (DECL_NAME (s1) == NULL - || DECL_NAME (s1) != DECL_NAME (s2)) + if (DECL_NAME (s1) != DECL_NAME (s2)) break; result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2)); + + if (result != 1 && !DECL_NAME (s1)) + break; if (result == 0) { tu->val = 0; @@ -1264,28 +1265,31 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2) { bool ok = false; - if (DECL_NAME (s1) != NULL) - for (s2 = TYPE_FIELDS (t2); s2; s2 = TREE_CHAIN (s2)) - if (DECL_NAME (s1) == DECL_NAME (s2)) - { - int result; - result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2)); - if (result == 0) - { - tu->val = 0; - return 0; - } - if (result == 2) - needs_warning = true; + for (s2 = TYPE_FIELDS (t2); s2; s2 = TREE_CHAIN (s2)) + if (DECL_NAME (s1) == DECL_NAME (s2)) + { + int result; - if (TREE_CODE (s1) == FIELD_DECL - && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1), - DECL_FIELD_BIT_OFFSET (s2)) != 1) - break; + result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2)); + + if (result != 1 && !DECL_NAME (s1)) + continue; + if (result == 0) + { + tu->val = 0; + return 0; + } + if (result == 2) + needs_warning = true; - ok = true; + if (TREE_CODE (s1) == FIELD_DECL + && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1), + DECL_FIELD_BIT_OFFSET (s2)) != 1) break; - } + + ok = true; + break; + } if (!ok) { tu->val = 0; |