Message ID | 559ECD49.7070701@oracle.com |
---|---|
State | New |
Headers | show |
On 07/09/2015 03:36 PM, Paolo Carlini wrote: > Finally, we do *not* reject, as we should, the line: > > template<> enum A<char>::E : char { echar }; > > Then, overall, is it Ok to simply suppress the pedwarn in C++11, and > xfail for now the error? Should I open a new, separate bug report about > the latter? (note that the issue, failing to reject an explicit > specialization after instantiation, doesn't sound new to me and seems > more general than enum-related issues...) I don't think it's a more general issue. I note that the specialization seems to append to the enumerator list somehow: int i = A<char>::eT + A<char>::echar; // accepted?!? I think we should fix this before we remove the pedwarn. Jason
Hi, On 07/09/2015 10:53 PM, Jason Merrill wrote: > On 07/09/2015 03:36 PM, Paolo Carlini wrote: >> Finally, we do *not* reject, as we should, the line: >> >> template<> enum A<char>::E : char { echar }; >> >> Then, overall, is it Ok to simply suppress the pedwarn in C++11, and >> xfail for now the error? Should I open a new, separate bug report about >> the latter? (note that the issue, failing to reject an explicit >> specialization after instantiation, doesn't sound new to me and seems >> more general than enum-related issues...) > > I don't think it's a more general issue. I note that the > specialization seems to append to the enumerator list somehow: > > int i = A<char>::eT + A<char>::echar; // accepted?!? Annoying :( Indeed, I can see that the append already happened by the time maybe_process_partial_specialization is called the fourth time. Let's see if I can make some progress on that. Thanks, Paolo.
Index: cp/parser.c =================================================================== --- cp/parser.c (revision 225614) +++ cp/parser.c (working copy) @@ -15827,8 +15827,9 @@ cp_parser_enum_specifier (cp_parser* parser) type = TREE_TYPE (name); if (TREE_CODE (type) == TYPENAME_TYPE) { - /* Are template enums allowed in ISO? */ - if (template_parm_scope_p ()) + /* Template enums are allowed in C++11. */ + if (template_parm_scope_p () + && cxx_dialect < cxx11) pedwarn (type_start_token->location, OPT_Wpedantic, "%qD is an enumeration template", name); /* ignore a typename reference, for it will be solved by name Index: cp/pt.c =================================================================== --- cp/pt.c (revision 225614) +++ cp/pt.c (working copy) @@ -970,11 +970,10 @@ maybe_process_partial_specialization (tree type) } else if (processing_specialization) { - /* Someday C++0x may allow for enum template specialization. */ + /* Under DR 1206 enum template specializations are allowed. */ 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 { error ("explicit specialization of non-template %qT", type); Index: testsuite/g++.dg/cpp0x/enum30.C =================================================================== --- testsuite/g++.dg/cpp0x/enum30.C (revision 0) +++ testsuite/g++.dg/cpp0x/enum30.C (working copy) @@ -0,0 +1,20 @@ +// PR c++/61491, DR 1206 +// { dg-do compile { target c++11 } } + +template <class D> struct Base +{ + enum class E : unsigned; + E e; + Base(E e) : e(e) {} +}; + +struct X; + +template<> enum class Base<X>::E : unsigned { a, b }; + +struct X : Base<X> +{ + X() : Base<X>(E::b) {} +}; + +X x; Index: testsuite/g++.dg/cpp0x/enum31.C =================================================================== --- testsuite/g++.dg/cpp0x/enum31.C (revision 0) +++ testsuite/g++.dg/cpp0x/enum31.C (working copy) @@ -0,0 +1,14 @@ +// DR 1206, PR c++/61491 +// { dg-do compile { target c++11 } } + +template<class T> struct A { + enum E : T; + enum class S : T; +}; + +template<> enum A<int>::E : int { eint }; +template<> enum class A<int>::S : int { sint }; +template<class T> enum A<T>::E : T { eT }; +template<class T> enum class A<T>::S : T { sT }; +template<> enum A<char>::E : char { echar }; // { dg-error "after instantiation" "" { xfail *-*-* } } +template<> enum class A<char>::S : char { schar };