PR c++/51248
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Dec 2011 22:26:13 +0000 (22:26 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 14 Dec 2011 22:26:13 +0000 (22:26 +0000)
* decl.c (copy_type_enum): Also update variants.
(finish_enum): Allow variants of complete enums.

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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/enum2.C [new file with mode: 0644]

index 2c20ae2..6677af3 100644 (file)
@@ -1,3 +1,9 @@
+2011-12-14  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51248
+       * decl.c (copy_type_enum): Also update variants.
+       (finish_enum): Allow variants of complete enums.
+
 2011-12-14  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/51475
index 5a4e027..480d211 100644 (file)
@@ -11908,15 +11908,19 @@ xref_basetypes (tree ref, tree base_list)
 static void
 copy_type_enum (tree dst, tree src)
 {
-  TYPE_MIN_VALUE (dst) = TYPE_MIN_VALUE (src);
-  TYPE_MAX_VALUE (dst) = TYPE_MAX_VALUE (src);
-  TYPE_SIZE (dst) = TYPE_SIZE (src);
-  TYPE_SIZE_UNIT (dst) = TYPE_SIZE_UNIT (src);
-  SET_TYPE_MODE (dst, TYPE_MODE (src));
-  TYPE_PRECISION (dst) = TYPE_PRECISION (src);
-  TYPE_ALIGN (dst) = TYPE_ALIGN (src);
-  TYPE_USER_ALIGN (dst) = TYPE_USER_ALIGN (src);
-  TYPE_UNSIGNED (dst) = TYPE_UNSIGNED (src);
+  tree t;
+  for (t = dst; t; t = TYPE_NEXT_VARIANT (t))
+    {
+      TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (src);
+      TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (src);
+      TYPE_SIZE (t) = TYPE_SIZE (src);
+      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (src);
+      SET_TYPE_MODE (dst, TYPE_MODE (src));
+      TYPE_PRECISION (t) = TYPE_PRECISION (src);
+      TYPE_ALIGN (t) = TYPE_ALIGN (src);
+      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (src);
+      TYPE_UNSIGNED (t) = TYPE_UNSIGNED (src);
+    }
 }
 
 /* Begin compiling the definition of an enumeration type.
@@ -12285,9 +12289,12 @@ finish_enum (tree enumtype)
       return;
     }
 
-  /* Here there should not be any variants of this type.  */
+  /* If this is a forward declaration, there should not be any variants,
+     though we can get a variant in the middle of an enum-specifier with
+     wacky code like 'enum E { e = sizeof(const E*) };'  */
   gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype)
-             && !TYPE_NEXT_VARIANT (enumtype));
+             && (TYPE_VALUES (enumtype)
+                 || !TYPE_NEXT_VARIANT (enumtype)));
 }
 
 /* Build and install a CONST_DECL for an enumeration constant of the
index ab5cca0..e276892 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-14  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51248
+       * g++.dg/other/enum2.C: New.
+
 2011-12-14  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/51475
diff --git a/gcc/testsuite/g++.dg/other/enum2.C b/gcc/testsuite/g++.dg/other/enum2.C
new file mode 100644 (file)
index 0000000..3a28f25
--- /dev/null
@@ -0,0 +1,3 @@
+// PR c++/51248
+
+enum E { e = sizeof(const E*) };