diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/enum35.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/enum36.C | 14 |
5 files changed, 60 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2d9c0b1..8228c8f0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index c0d0a60..9ce094e 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 35c31e7..a8a4a11 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..bcc1b26 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum35.C @@ -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 index 0000000..4859670 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum36.C @@ -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)); +} |