From eab01c18fdf287aaac60224ddbecae6574631b7b Mon Sep 17 00:00:00 2001 From: Mukesh Kapoor Date: Tue, 24 Oct 2017 13:49:13 +0000 Subject: [PATCH] re PR c++/82307 (unscoped enum-base incorrect cast) /cp 2017-10-24 Mukesh Kapoor Paolo Carlini 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 Paolo Carlini PR c++/82307 * g++.dg/cpp0x/enum35.C: New. * g++.dg/cpp0x/enum36.C: Likewise. Co-Authored-By: Paolo Carlini From-SVN: r254046 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cvt.c | 21 ++++++++++++++++++--- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/cpp0x/enum35.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/enum36.C | 14 ++++++++++++++ 5 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum35.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum36.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2d9c0b133c0..8228c8f0a9d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-10-24 Mukesh Kapoor + Paolo Carlini + + 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 PR c++/80449 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index c0d0a600562..9ce094eb2a5 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 35c31e70b61..a8a4a119886 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2017-10-24 Mukesh Kapoor + Paolo Carlini + + PR c++/82307 + * g++.dg/cpp0x/enum35.C: New. + * g++.dg/cpp0x/enum36.C: Likewise. + 2017-10-24 H.J. Lu 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 index 00000000000..bcc1b26b390 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum35.C @@ -0,0 +1,14 @@ +// PR c++/82307 +// { dg-do run { target c++11 } } + +#include + +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 index 00000000000..4859670309f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum36.C @@ -0,0 +1,14 @@ +// PR c++/82307 +// { dg-do run { target c++11 } } + +#include + +enum : short { VAL }; + +bool foo (int) { return true; } +bool foo (unsigned long long) { return false; } + +int main() +{ + assert (foo (VAL)); +} -- 2.30.2