diff mbox

[C++,RFC/Patch] PR c++/71665

Message ID 78408ffa-6e63-6d7e-8a59-e2bcfffdb0ad@oracle.com
State New
Headers show

Commit Message

Paolo Carlini July 28, 2016, 3:55 p.m. UTC
Hi,

On 28/07/2016 16:28, Jason Merrill wrote:
> On Thu, Jul 28, 2016 at 7:48 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
>> Ah sorry, I missed the *type* bit. The below passes testing on x86_64-linux.
>> I don't think we need to check the type again after cxx_constant_value?!?
> No, we don't.  The patch is OK.
>
>> While finally spending a decent amount of time on this issue I noticed that
>> current clang appears to enforce integral or *unscoped* enumeration type and
>> tweaking our code in the obvious way doesn't cause regressions, we of course
>> reject earlier (ie, not as "could not convert ‘(E)1’ from ‘E’ to ‘unsigned
>> int’") in build_enumerator snippets like:
>>
>> enum class E { e = 1 };
>>
>> class A
>> {
>>    enum { a = E::e };
>> };
> Sure, that change could improve diagnostic quality a bit.
Thanks Jason. Then I'm regression testing again the below and I mean to 
commit it later today.

Thanks again,
Paolo.

/////////////////////
/cp
2016-07-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71665
	* decl.c (build_enumerator): Check the type of the enumerator before
	calling cxx_constant_value.

/testsuite
2016-07-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/71665
	* g++.dg/cpp0x/pr71665-1.C: New.
	* g++.dg/cpp0x/pr71665-2.C: Likewise.
	* g++.dg/cpp0x/enum29.C: Adjust dg-error string.
	* g++.dg/ext/label10.C: Likewise.
	* g++.dg/parse/constant5.C: Likewise.
diff mbox

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 238822)
+++ cp/decl.c	(working copy)
@@ -13587,15 +13587,24 @@  build_enumerator (tree name, tree value, tree enum
 
 	  if (value != NULL_TREE)
 	    {
-	      value = cxx_constant_value (value);
-
-	      if (TREE_CODE (value) != INTEGER_CST
-		  || ! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
+	      if (! INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P
+		  (TREE_TYPE (value)))
 		{
-		  error ("enumerator value for %qD is not an integer constant",
-			 name);
+		  error ("enumerator for %qD must have integral or "
+			 "unscoped enumeration type", name);
 		  value = NULL_TREE;
 		}
+	      else
+		{
+		  value = cxx_constant_value (value);
+
+		  if (TREE_CODE (value) != INTEGER_CST)
+		    {
+		      error ("enumerator value for %qD is not an integer "
+			     "constant", name);
+		      value = NULL_TREE;
+		    }
+		}
 	    }
 	}
 
Index: testsuite/g++.dg/cpp0x/enum29.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum29.C	(revision 238822)
+++ testsuite/g++.dg/cpp0x/enum29.C	(working copy)
@@ -38,7 +38,7 @@  enum E0 { e0 = X0() };
 enum E1 { e1 = X1() };
 enum E2 { e2 = X2() };
 enum E3 { e3 = X3() };
-enum E4 { e4 = X4() };  // { dg-error "integer constant" }
+enum E4 { e4 = X4() };  // { dg-error "integral" }
 enum E5 { e5 = X5() };  // { dg-error "ambiguous" }
 
 enum F0 : int { f0 = X0() };
Index: testsuite/g++.dg/cpp0x/pr71665-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr71665-1.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr71665-1.C	(working copy)
@@ -0,0 +1,8 @@ 
+// PR c++/71665
+// { dg-do compile { target c++11 } }
+
+class A 
+{
+  int f ();
+  enum { a = f }; // { dg-error "enumerator" }
+};
Index: testsuite/g++.dg/cpp0x/pr71665-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr71665-2.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr71665-2.C	(working copy)
@@ -0,0 +1,8 @@ 
+// PR c++/71665
+// { dg-do compile { target c++11 } }
+
+class A 
+{
+  enum class E { e = 1 };
+  enum { a = E::e };  // { dg-error "integral or unscoped enumeration" }
+};
Index: testsuite/g++.dg/ext/label10.C
===================================================================
--- testsuite/g++.dg/ext/label10.C	(revision 238822)
+++ testsuite/g++.dg/ext/label10.C	(working copy)
@@ -4,7 +4,7 @@ 
 
 template<int N> struct A
 {
-  enum { M = && N };	// { dg-error "referenced outside|cannot appear in|not an integer constant" }
+  enum { M = && N };	// { dg-error "referenced outside|cannot appear in|integral" }
 };
 
 A<0> a;
@@ -12,6 +12,6 @@  A<0> a;
 void foo ()
 {
   __label__ P;
-  enum { O = && P };	// { dg-error "cannot appear in|not an integer constant" }
+  enum { O = && P };	// { dg-error "cannot appear in|integral" }
   P:;
 }
Index: testsuite/g++.dg/parse/constant5.C
===================================================================
--- testsuite/g++.dg/parse/constant5.C	(revision 238822)
+++ testsuite/g++.dg/parse/constant5.C	(working copy)
@@ -1,7 +1,7 @@ 
 // { dg-options "-std=c++98 -pedantic-errors" }
 
 enum E { 
-  a = 24.2, // { dg-error "constant" }
+  a = 24.2, // { dg-error "integral|constant" }
   b = (int)3.7, 
   c = int(4.2),
   d = (int)(4.2 + 3.7), // { dg-error "constant" }