Hi,
On 28/07/2016 16:28, Jason Merrill wrote:
On Thu, Jul 28, 2016 at 7:48 AM, Paolo Carlini <paolo.carl...@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.carl...@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.carl...@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.
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" }