aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-12-14 17:26:13 -0500
committerJason Merrill <jason@gcc.gnu.org>2011-12-14 17:26:13 -0500
commit2f074b08d4b008177d3ed6304fc33932e099e43d (patch)
tree984187b8b10589fc31a6db3a3378989b3ced668b
parent3c72114c42aa6c7778f264579c16ad168753648b (diff)
downloadgcc-2f074b08d4b008177d3ed6304fc33932e099e43d.zip
gcc-2f074b08d4b008177d3ed6304fc33932e099e43d.tar.gz
gcc-2f074b08d4b008177d3ed6304fc33932e099e43d.tar.bz2
re PR c++/51248 (ICE with pointer to enum)
PR c++/51248 * decl.c (copy_type_enum): Also update variants. (finish_enum): Allow variants of complete enums. From-SVN: r182345
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/enum2.C3
4 files changed, 32 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2c20ae2..6677af3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5a4e027..480d211 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ab5cca0..e276892 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..3a28f25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/enum2.C
@@ -0,0 +1,3 @@
+// PR c++/51248
+
+enum E { e = sizeof(const E*) };