re PR c++/71665 (ICE on invalid C++ code with non-integral constant enumerator value...
authorPaolo Carlini <paolo.carlini@oracle.com>
Thu, 28 Jul 2016 18:43:29 +0000 (18:43 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 28 Jul 2016 18:43:29 +0000 (18:43 +0000)
/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.

From-SVN: r238828

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum29.C
gcc/testsuite/g++.dg/cpp0x/pr71665-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/pr71665-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/label10.C
gcc/testsuite/g++.dg/parse/constant5.C

index 99c7c28..cf692c9 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2016-07-27  Jason Merrill  <jason@redhat.com>
 
        PR c++/71747
index 08fa95d..c7bad41 100644 (file)
@@ -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;
+                   }
+               }
            }
        }
 
index c9746c6..1bfcdeb 100644 (file)
@@ -1,3 +1,12 @@
+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.
+
 2016-07-28  Steven G. Kargl  <kargl@gcc.gnu.org>
 
        PR fortran/71859
index f24a6a2..63ecf7e 100644 (file)
@@ -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 (file)
index 0000000..0c33241
--- /dev/null
@@ -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 (file)
index 0000000..aa6d9ad
--- /dev/null
@@ -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 632b242..62d235d 100644 (file)
@@ -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 f868108..517fbdf 100644 (file)
@@ -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" }