OSDN Git Service

PR c/4784
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 May 2010 16:19:28 +0000 (16:19 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 9 May 2010 16:19:28 +0000 (16:19 +0000)
* c-decl.c (detect_field_duplicates_hash): New.  Handle anonymous
structures and unions recursively.
(detect_field_duplicates): Move duplicate detection with a hash to
detect_field_duplicates_hash.  Always use a hash if anonymous
structures or unions are present.
* doc/extend.texi (Unnamed Fields): Document that duplicate fields
give errors.

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

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

gcc/ChangeLog
gcc/c-decl.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/anon-struct-9.c [new file with mode: 0644]

index 3a9d1f9..8879737 100644 (file)
@@ -1,3 +1,14 @@
+2010-05-09  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/4784
+       * c-decl.c (detect_field_duplicates_hash): New.  Handle anonymous
+       structures and unions recursively.
+       (detect_field_duplicates): Move duplicate detection with a hash to
+       detect_field_duplicates_hash.  Always use a hash if anonymous
+       structures or unions are present.
+       * doc/extend.texi (Unnamed Fields): Document that duplicate fields
+       give errors.
+
 2010-05-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/44046
index dd07b65..03211d6 100644 (file)
@@ -6629,6 +6629,31 @@ grokfield (location_t loc,
   return value;
 }
 \f
+/* Subroutine of detect_field_duplicates: add the fields of FIELDLIST
+   to HTAB, giving errors for any duplicates.  */
+
+static void
+detect_field_duplicates_hash (tree fieldlist, htab_t htab)
+{
+  tree x, y;
+  void **slot;
+
+  for (x = fieldlist; x ; x = TREE_CHAIN (x))
+    if ((y = DECL_NAME (x)) != 0)
+      {
+       slot = htab_find_slot (htab, y, INSERT);
+       if (*slot)
+         {
+           error ("duplicate member %q+D", x);
+           DECL_NAME (x) = NULL_TREE;
+         }
+       *slot = y;
+      }
+    else if (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+            || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+      detect_field_duplicates_hash (TYPE_FIELDS (TREE_TYPE (x)), htab);
+}
+
 /* Generate an error for any duplicate field names in FIELDLIST.  Munge
    the list such that this does not present a problem later.  */
 
@@ -6647,11 +6672,16 @@ detect_field_duplicates (tree fieldlist)
     return;
   do {
     timeout--;
+    if (DECL_NAME (x) == NULL_TREE
+       && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+           || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+      timeout = 0;
     x = TREE_CHAIN (x);
   } while (timeout > 0 && x);
 
-  /* If there were "few" fields, avoid the overhead of allocating
-     a hash table.  Instead just do the nested traversal thing.  */
+  /* If there were "few" fields and no anonymous structures or unions,
+     avoid the overhead of allocating a hash table.  Instead just do
+     the nested traversal thing.  */
   if (timeout > 0)
     {
       for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
@@ -6668,20 +6698,8 @@ detect_field_duplicates (tree fieldlist)
   else
     {
       htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
-      void **slot;
-
-      for (x = fieldlist; x ; x = TREE_CHAIN (x))
-       if ((y = DECL_NAME (x)) != 0)
-         {
-           slot = htab_find_slot (htab, y, INSERT);
-           if (*slot)
-             {
-               error ("duplicate member %q+D", x);
-               DECL_NAME (x) = NULL_TREE;
-             }
-           *slot = y;
-         }
 
+      detect_field_duplicates_hash (fieldlist, htab);
       htab_delete (htab);
     }
 }
index bf74863..7a495eb 100644 (file)
@@ -12760,8 +12760,7 @@ struct @{
 @end smallexample
 
 It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
-Such constructs are not supported and must be avoided.  In the future,
-such constructs may be detected and treated as compilation errors.
+The compiler gives errors for such constructs.
 
 @opindex fms-extensions
 Unless @option{-fms-extensions} is used, the unnamed field must be a
index bd28f18..cf4140d 100644 (file)
@@ -1,3 +1,8 @@
+2010-05-09  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/4784
+       * gcc.dg/anon-struct-9.c: New test.
+
 2010-05-09  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/44043
diff --git a/gcc/testsuite/gcc.dg/anon-struct-9.c b/gcc/testsuite/gcc.dg/anon-struct-9.c
new file mode 100644 (file)
index 0000000..2658ccb
--- /dev/null
@@ -0,0 +1,129 @@
+/* Test for diagnostics for duplicate member names in anonymous
+   structures and unions.  PR 4784.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct s1
+{
+  int x;
+  struct
+  {
+    int x; /* { dg-error "duplicate member" } */
+  };
+};
+
+struct s2
+{
+  struct
+  {
+    int a;
+    struct
+    {
+      int b;
+    };
+  };
+  struct
+  {
+    int b; /* { dg-error "duplicate member" } */
+  };
+};
+
+struct s3
+{
+  struct
+  {
+    int a;
+    struct
+    {
+      int b;
+    };
+  };
+  struct
+  {
+    int b; /* { dg-error "duplicate member" } */
+    int c;
+  };
+};
+
+struct s4
+{
+  int x;
+  struct
+  {
+    int x;
+  } y;
+};
+
+union u1
+{
+  int x;
+  union
+  {
+    int x; /* { dg-error "duplicate member" } */
+  };
+};
+
+union u2
+{
+  union
+  {
+    int a;
+    union
+    {
+      int b;
+    };
+  };
+  union
+  {
+    int b; /* { dg-error "duplicate member" } */
+  };
+};
+
+union u3
+{
+  union
+  {
+    int a;
+    union
+    {
+      int b;
+    };
+  };
+  union
+  {
+    int b; /* { dg-error "duplicate member" } */
+    int c;
+  };
+};
+
+union u4
+{
+  int x;
+  union
+  {
+    int x;
+  } y;
+};
+
+#define D10(x) int x##0; int x##1; int x##2; int x##3; int x##4; int x##5; int x##6; int x##7; int x##8; int x##9;
+#define D100(x) D10(x##0) D10(x##1) D10(x##2) D10(x##3) D10(x##4) D10(x##5) D10(x##6) D10(x##7) D10(x##8) D10(x##9)
+
+#define S10(x) struct { D100(x##0) }; struct { D100(x##1) }; struct { D100(x##2) }; struct { D100(x##3) }; struct { D100(x##4) }; struct { D100(x##5) }; struct { D100(x##6) }; struct { D100(x##7) }; struct { D100(x##8) }; struct { D100(x##9) };
+
+struct sbig
+{
+  S10(a)
+  S10(b)
+  S10(c)
+  S10(d)
+  S10(e)
+  S10(f)
+  S10(g)
+  S10(h)
+  S10(i)
+  S10(j)
+  struct
+  {
+    int a123; /* { dg-error "duplicate member" } */
+  };
+};