re PR c++/37816 ([c++0x] Invalid handling of scoped enums defined at class scope)
authorJason Merrill <jason@redhat.com>
Tue, 7 Jul 2009 17:55:26 +0000 (13:55 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 7 Jul 2009 17:55:26 +0000 (13:55 -0400)
PR c++/37816
* decl.c (build_enumerator): Don't add enumerators for a
scoped enum to the enclosing class.

PR c++/40639
* decl.c (start_enum): Allow dependent underlying type.

PR c++/40633
* decl.c (finish_enum): Finish scope even in a template.

From-SVN: r149341

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/enum5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/enum6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/enum7.C [new file with mode: 0644]

index 1540827..a0eedeb 100644 (file)
@@ -1,3 +1,15 @@
+2009-07-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37816
+       * decl.c (build_enumerator): Don't add enumerators for a
+       scoped enum to the enclosing class.
+
+       PR c++/40639
+       * decl.c (start_enum): Allow dependent underlying type.
+
+       PR c++/40633
+       * decl.c (finish_enum): Finish scope even in a template.
+
 2009-07-07  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * init.c: Replace %J by an explicit location. Update all calls.
index c0dccdc..d7a0e0d 100644 (file)
@@ -11049,7 +11049,7 @@ start_enum (tree name, tree underlying_type, bool scoped_enum_p)
           TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
           ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
         }
-      else
+      else if (!dependent_type_p (underlying_type))
         error ("underlying type %<%T%> of %<%T%> must be an integral type", 
                underlying_type, enumtype);
     }
@@ -11095,6 +11095,8 @@ finish_enum (tree enumtype)
        TREE_TYPE (TREE_VALUE (values)) = enumtype;
       if (at_function_scope_p ())
        add_stmt (build_min (TAG_DEFN, enumtype));
+      if (SCOPED_ENUM_P (enumtype))
+       finish_scope ();
       return;
     }
 
@@ -11410,7 +11412,7 @@ build_enumerator (tree name, tree value, tree enumtype)
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
-  if (context && context == current_class_type)
+  if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
     /* In something like `struct S { enum E { i = 7 }; };' we put `i'
        on the TYPE_FIELDS list for `S'.  (That's so that you can say
        things like `S::i' later.)  */
index 95b0406..9e4ec3d 100644 (file)
@@ -1,3 +1,17 @@
+2009-07-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37816
+       * g++.dg/cpp0x/enum7.C: New.
+
+       PR c++/37946
+       * g++.dg/cpp0x/enum6.C: New.
+
+       PR c++/40639
+       * g++.dg/cpp0x/enum5.C: New.
+
+       PR c++/40633
+       * g++.dg/cpp0x/enum4.C: New.
+
 2009-07-07  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * gcc.dg/format/gcc_diag-1.c: Remove tests for %J.
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum4.C b/gcc/testsuite/g++.dg/cpp0x/enum4.C
new file mode 100644 (file)
index 0000000..002edf0
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/40633
+// { dg-options "-std=c++0x" }
+
+template< typename T >
+struct wrap {
+   enum class E { val };
+};
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum5.C b/gcc/testsuite/g++.dg/cpp0x/enum5.C
new file mode 100644 (file)
index 0000000..c4ceebe
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/40639
+// { dg-options "-std=c++0x" }
+
+template< typename T >
+struct wrap {
+   enum E : T { val };
+};
+
+template< typename T >
+struct dependant {
+   enum E : typename T::type { val };
+};
+
+template<typename T>
+struct identity {
+   typedef T type;
+};
+
+wrap<int> x;
+dependant<identity<int>> y;
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum6.C b/gcc/testsuite/g++.dg/cpp0x/enum6.C
new file mode 100644 (file)
index 0000000..e063984
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/37946
+// { dg-options "-std=c++0x" }
+
+enum class E : char
+{
+    e1,
+    e2
+};
+
+inline E operator| (E a1, E a2)
+{
+    char ret = static_cast<char> (a1)
+        | static_cast<char> (a2);
+    return static_cast<E>(ret);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum7.C b/gcc/testsuite/g++.dg/cpp0x/enum7.C
new file mode 100644 (file)
index 0000000..407672a
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/37816
+// { dg-options "-std=c++0x" }
+
+class A
+{
+  enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
+  enum class Alert { Green, Yellow, Red };
+  static const Color x = Red;  // { dg-error "" }
+  static const Color y = Color::Red;
+  static const Alert z = Alert::Red;
+};