Hi,
following up to a short off-line exchange with Nathan, I'm sending a
reworked patch which - among other things - avoids regressing on the
second testcase (cpp0x/enum36.C). Tested x86_64-linux.
Thanks,
Paolo.
////////////////////
/cp
2017-10-23 Mukesh Kapoor <mukesh.kap...@oracle.com>
Paolo Carlini <paolo.carl...@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-23 Mukesh Kapoor <mukesh.kap...@oracle.com>
Paolo Carlini <paolo.carl...@oracle.com>
PR c++/82307
* g++.dg/cpp0x/enum35.C: New.
* g++.dg/cpp0x/enum36.C: Likewise.
Index: cp/cvt.c
===================================================================
--- cp/cvt.c (revision 254005)
+++ cp/cvt.c (working copy)
@@ -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: testsuite/g++.dg/cpp0x/enum35.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum35.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/enum35.C (working copy)
@@ -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));
+}
Index: testsuite/g++.dg/cpp0x/enum36.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum36.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/enum36.C (working copy)
@@ -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));
+}