Re: [C++ PATCH, RFC] PR c++/61491

2014-06-15 Thread Jason Merrill

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

2014-06-15 Thread Ville Voutilainen
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

2014-06-13 Thread Jason Merrill
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

2014-06-13 Thread Ville Voutilainen
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

2014-06-13 Thread Jason Merrill

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

2014-06-13 Thread Ville Voutilainen
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

2014-06-12 Thread Ville Voutilainen
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

2014-06-12 Thread Ville Voutilainen
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 };