Re: [C++ PATCH, RFC] PR c++/61491
On 06/13/2014 02:45 PM, Ville Voutilainen wrote: Yeah, my point was just that unscoped enums (with an explicit underlying type) as such are eligible for specialization Yes, but if there is a template definition for the enum available when the specialization is declared, the enum template is implicitly instantiated along with its containing class, so the specialization is ill-formed because you can't define a specialization that has already been instantiated. Which is what the example in the standard illustrates. Jason
Re: [C++ PATCH, RFC] PR c++/61491
On 15 June 2014 16:37, Jason Merrill ja...@redhat.com wrote: Yes, but if there is a template definition for the enum available when the specialization is declared, the enum template is implicitly instantiated along with its containing class, so the specialization is ill-formed because you can't define a specialization that has already been instantiated. Which is what the example in the standard illustrates. Ah, I see. So it's not just the difference in the underlying type, it's that an unscoped enum cannot be specialized to begin with, even when it has an underlying type. Ok, then the patch does need further work. I don't know how to solve that part yet, guidance would be welcome.
Re: [C++ PATCH, RFC] PR c++/61491
This needs a test that we complain about a specialization of an unscoped enum. Perhaps just the test from 14.7p6?? templateclass T struct A { enum E: T; enum class S: T; }; template enum Aint::E: int { eint }; // OK template enum class Aint::S: int { sint }; // OK templateclass T enum AT::E: T { eT }; templateclass T enum class AT::S: T { sT }; template enum Achar::E: int { echar }; // ill-formed, Achar::E was instantiated when Achar was instantiated template enum class Achar::S: int { schar }; // OK
Re: [C++ PATCH, RFC] PR c++/61491
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 000..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 Baseint::E : int { a, b }; + +template class D struct Base2 +{ + enum class E : D; // { dg-error previous definition } +}; + +template enum class Base2int::E : char { a, b }; // { dg-error different underlying type } + +template class D struct Base3 +{ + enum E : D; +}; + +template enum Base3int::E : int { a, b }; + +template class D struct Base4 +{ + enum E : D; // { dg-error previous definition } +}; + +template enum Base4int::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 Base6int::E {a,b}; // { dg-error redeclaration|enumerator value } + +template class D struct Base7 +{ + enum E {}; +}; + +template enum Base7int::E {};
Re: [C++ PATCH, RFC] PR c++/61491
On 06/13/2014 02:05 PM, Ville Voutilainen wrote: that example has ones that have the wrong underlying type. Good point. That was fixed after the DR was incorporated into the WP, which now says templateclass T struct A { enum E : T; enum class S : T; }; template enum Aint::E : int { eint }; // OK template enum class Aint::S : int { sint }; // OK templateclass T enum AT::E : T { eT }; templateclass T enum class AT::S : T { sT }; template enum Achar::E : char { echar }; // ill-formed, Achar::E was instantiated // when Achar was instantiated template enum class Achar::S : char { schar }; // OK Jason
Re: [C++ PATCH, RFC] PR c++/61491
On 13 June 2014 21:33, Jason Merrill ja...@redhat.com wrote: On 06/13/2014 02:05 PM, Ville Voutilainen wrote: that example has ones that have the wrong underlying type. Good point. That was fixed after the DR was incorporated into the WP, which now says templateclass T struct A { enum E : T; enum class S : T; }; template enum Aint::E : int { eint }; // OK template enum class Aint::S : int { sint }; // OK templateclass T enum AT::E : T { eT }; templateclass T enum class AT::S : T { sT }; template enum Achar::E : char { echar }; // ill-formed, Achar::E was instantiated // when Achar was instantiated template enum class Achar::S : char { schar }; // OK Yeah, my point was just that unscoped enums (with an explicit underlying type) as such are eligible for specialization, hence I added tests for that, and also for unscoped enums with no explicit underlying type, which cannot really be specialized since you either can't just declare the enum, or alternatively the members end up being redeclarations. So, is the last patch ok, or does it need further work?
[C++ PATCH, RFC] PR c++/61491
DR1206 allows explicit specializations of member enumerations of class templates, so just remove the pedwarn about it. Tested on Linux-x64. Not bootstrapped. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d267a5c..97eadeb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -967,11 +967,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 000..c105782 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr61491.C @@ -0,0 +1,12 @@ +// { 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 : unsigned; +}; + +struct X; + +template enum class BaseX::E : unsigned { a, b }; pr61491.changelog Description: Binary data
Re: [C++ PATCH, RFC] PR c++/61491
On 13 June 2014 01:37, Ville Voutilainen ville.voutilai...@gmail.com wrote: DR1206 allows explicit specializations of member enumerations of class templates, so just remove the pedwarn about it. Tested on Linux-x64. Not bootstrapped. Argh, also remove the old comment, new patch attached. 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 000..c105782 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr61491.C @@ -0,0 +1,12 @@ +// { 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 : unsigned; +}; + +struct X; + +template enum class BaseX::E : unsigned { a, b };