From f064da6af5b5a348dce6eacb2ac72062bfdf12b7 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 28 Jul 2016 18:43:29 +0000 Subject: [PATCH] re PR c++/71665 (ICE on invalid C++ code with non-integral constant enumerator value: in cxx_eval_constant_expression, at cp/constexpr.c:3918) /cp 2016-07-28 Paolo Carlini PR c++/71665 * decl.c (build_enumerator): Check the type of the enumerator before calling cxx_constant_value. /testsuite 2016-07-28 Paolo Carlini 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. From-SVN: r238828 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/decl.c | 21 +++++++++++++++------ gcc/testsuite/ChangeLog | 9 +++++++++ gcc/testsuite/g++.dg/cpp0x/enum29.C | 2 +- gcc/testsuite/g++.dg/cpp0x/pr71665-1.C | 8 ++++++++ gcc/testsuite/g++.dg/cpp0x/pr71665-2.C | 8 ++++++++ gcc/testsuite/g++.dg/ext/label10.C | 4 ++-- gcc/testsuite/g++.dg/parse/constant5.C | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr71665-1.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr71665-2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 99c7c28d0a11..cf692c9fbc6c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-07-28 Paolo Carlini + + PR c++/71665 + * decl.c (build_enumerator): Check the type of the enumerator before + calling cxx_constant_value. + 2016-07-27 Jason Merrill PR c++/71747 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 08fa95dc0e6d..c7bad41c99b7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13587,15 +13587,24 @@ build_enumerator (tree name, tree value, tree enumtype, tree attributes, 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; + } + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c9746c6ad06b..1bfcdeb40ebd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2016-07-28 Paolo Carlini + + 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. + 2016-07-28 Steven G. Kargl PR fortran/71859 diff --git a/gcc/testsuite/g++.dg/cpp0x/enum29.C b/gcc/testsuite/g++.dg/cpp0x/enum29.C index f24a6a2a958e..63ecf7ebe398 100644 --- a/gcc/testsuite/g++.dg/cpp0x/enum29.C +++ b/gcc/testsuite/g++.dg/cpp0x/enum29.C @@ -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() }; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71665-1.C b/gcc/testsuite/g++.dg/cpp0x/pr71665-1.C new file mode 100644 index 000000000000..0c33241bf983 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71665-1.C @@ -0,0 +1,8 @@ +// PR c++/71665 +// { dg-do compile { target c++11 } } + +class A +{ + int f (); + enum { a = f }; // { dg-error "enumerator" } +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/pr71665-2.C b/gcc/testsuite/g++.dg/cpp0x/pr71665-2.C new file mode 100644 index 000000000000..aa6d9ad80b29 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr71665-2.C @@ -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" } +}; diff --git a/gcc/testsuite/g++.dg/ext/label10.C b/gcc/testsuite/g++.dg/ext/label10.C index 632b2426ed51..62d235d7d873 100644 --- a/gcc/testsuite/g++.dg/ext/label10.C +++ b/gcc/testsuite/g++.dg/ext/label10.C @@ -4,7 +4,7 @@ template 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:; } diff --git a/gcc/testsuite/g++.dg/parse/constant5.C b/gcc/testsuite/g++.dg/parse/constant5.C index f868108a644a..517fbdf35b0a 100644 --- a/gcc/testsuite/g++.dg/parse/constant5.C +++ b/gcc/testsuite/g++.dg/parse/constant5.C @@ -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" }