On 13 June 2014 19:56, Jason Merrill <ja...@redhat.com> wrote: > This needs a test that we complain about a specialization of an unscoped > enum. Perhaps just the test from 14.7p6??
Well, a specialization of an unscoped enum with the proper underlying type is fine, and that example has ones that have the wrong underlying type. Unscoped enums with no underlying type are a different case. How about the attached patch?
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d267a5c..507585f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -966,12 +966,8 @@ maybe_process_partial_specialization (tree type) } else if (processing_specialization) { - /* Someday C++0x may allow for enum template specialization. */ - if (cxx_dialect > cxx98 && TREE_CODE (type) == ENUMERAL_TYPE - && CLASS_TYPE_P (context) && CLASSTYPE_USE_TEMPLATE (context)) - pedwarn (input_location, OPT_Wpedantic, "template specialization " - "of %qD not allowed by ISO C++", type); - else + if (!(cxx_dialect > cxx98 && TREE_CODE (type) == ENUMERAL_TYPE + && CLASS_TYPE_P (context) && CLASSTYPE_USE_TEMPLATE (context))) { error ("explicit specialization of non-template %qT", type); return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr61491.C b/gcc/testsuite/g++.dg/cpp0x/pr61491.C new file mode 100644 index 0000000..191cfd3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr61491.C @@ -0,0 +1,50 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-pedantic" } +// DR 1206 (explicit specialization of a member enumeration of a class template) + +template <class D> struct Base +{ + enum class E : D; +}; + +template<> enum class Base<int>::E : int { a, b }; + +template <class D> struct Base2 +{ + enum class E : D; // { dg-error "previous definition" } +}; + +template<> enum class Base2<int>::E : char { a, b }; // { dg-error "different underlying type" } + +template <class D> struct Base3 +{ + enum E : D; +}; + +template<> enum Base3<int>::E : int { a, b }; + +template <class D> struct Base4 +{ + enum E : D; // { dg-error "previous definition" } +}; + +template<> enum Base4<int>::E : char { a, b }; // { dg-error "different underlying type" } + +template <class D> struct Base5 +{ + enum E; // { dg-error "use of enum.*without previous declaration" } +}; + +template <class D> struct Base6 +{ + enum E {a,b}; +}; + +template<> enum Base6<int>::E {a,b}; // { dg-error "redeclaration|enumerator value" } + +template <class D> struct Base7 +{ + enum E {}; +}; + +template<> enum Base7<int>::E {};