re PR c++/82307 (unscoped enum-base incorrect cast)
authorMukesh Kapoor <mukesh.kapoor@oracle.com>
Tue, 24 Oct 2017 13:49:13 +0000 (13:49 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 24 Oct 2017 13:49:13 +0000 (13:49 +0000)
/cp
2017-10-24  Mukesh Kapoor  <mukesh.kapoor@oracle.com>
    Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/82307
* cvt.c (type_promotes_to): Implement C++17, 7.6/4, about unscoped
enumeration type whose underlying type is fixed.

/testsuite
2017-10-24  Mukesh Kapoor  <mukesh.kapoor@oracle.com>
    Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/82307
* g++.dg/cpp0x/enum35.C: New.
* g++.dg/cpp0x/enum36.C: Likewise.

Co-Authored-By: Paolo Carlini <paolo.carlini@oracle.com>
From-SVN: r254046

gcc/cp/ChangeLog
gcc/cp/cvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/enum35.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/enum36.C [new file with mode: 0644]

index 2d9c0b133c028e318c511af06ade1fa05b156224..8228c8f0a9db7b144ccea4832b60afa9edd4c83c 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-24  Mukesh Kapoor  <mukesh.kapoor@oracle.com>
+           Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/82307
+       * cvt.c (type_promotes_to): Implement C++17, 7.6/4, about unscoped
+       enumeration type whose underlying type is fixed.
+
 2017-10-23  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/80449
index c0d0a6005628d96302587c1ff94cd33c23365faf..9ce094eb2a5b3bbfd9c5793e7504db345bd47df8 100644 (file)
@@ -1834,12 +1834,27 @@ type_promotes_to (tree type)
           || type == char32_type_node
           || type == wchar_type_node)
     {
+      tree prom = type;
+
+      if (TREE_CODE (type) == ENUMERAL_TYPE)
+       {
+         prom = ENUM_UNDERLYING_TYPE (prom);
+         if (!ENUM_IS_SCOPED (type)
+             && ENUM_FIXED_UNDERLYING_TYPE_P (type))
+           {
+             /* ISO C++17, 7.6/4.  A prvalue of an unscoped enumeration type
+                whose underlying type is fixed (10.2) can be converted to a
+                prvalue of its underlying type. Moreover, if integral promotion
+                can be applied to its underlying type, a prvalue of an unscoped
+                enumeration type whose underlying type is fixed can also be 
+                converted to a prvalue of the promoted underlying type.  */
+             return type_promotes_to (prom);
+           }
+       }
+
       int precision = MAX (TYPE_PRECISION (type),
                           TYPE_PRECISION (integer_type_node));
       tree totype = c_common_type_for_size (precision, 0);
-      tree prom = type;
-      if (TREE_CODE (prom) == ENUMERAL_TYPE)
-       prom = ENUM_UNDERLYING_TYPE (prom);
       if (TYPE_UNSIGNED (prom)
          && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
        prom = c_common_type_for_size (precision, 1);
index 35c31e70b617da5181f08dbda57ddf8fc94c6b3c..a8a4a119886f0c2f2e8a28cf7c9e1cd0f011b704 100644 (file)
@@ -1,3 +1,10 @@
+2017-10-24  Mukesh Kapoor  <mukesh.kapoor@oracle.com>
+           Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/82307
+       * g++.dg/cpp0x/enum35.C: New.
+       * g++.dg/cpp0x/enum36.C: Likewise.
+
 2017-10-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/82659
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum35.C b/gcc/testsuite/g++.dg/cpp0x/enum35.C
new file mode 100644 (file)
index 0000000..bcc1b26
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/82307
+// { dg-do run { target c++11 } }
+
+#include <cassert>
+
+enum : unsigned long long { VAL };
+
+bool foo (unsigned long long) { return true; }
+bool foo (int) { return false; }
+
+int main()
+{
+  assert (foo(VAL));
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum36.C b/gcc/testsuite/g++.dg/cpp0x/enum36.C
new file mode 100644 (file)
index 0000000..4859670
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/82307
+// { dg-do run { target c++11 } }
+
+#include <cassert>
+
+enum : short { VAL };
+
+bool foo (int) { return true; }
+bool foo (unsigned long long) { return false; }
+
+int main()
+{
+  assert (foo (VAL));
+}