From 8a089c4156e23977b16254511cbf791b7f0ddd01 Mon Sep 17 00:00:00 2001 From: paolo Date: Wed, 14 Aug 2013 21:42:54 +0000 Subject: [PATCH] /cp 2013-08-14 Paolo Carlini PR c++/51912 * cp-tree.h (LOOKUP_NO_NON_INTEGRAL): Add. * decl.c (case_conversion): Use it. * call.c (standard_conversion): Likewise. (implicit_conversion): Adjust. /testsuite 2013-08-14 Paolo Carlini PR c++/51912 * g++.dg/cpp0x/enum28.C: New. * g++.dg/cpp0x/enum15.C: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201754 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/call.c | 5 +++-- gcc/cp/cp-tree.h | 2 ++ gcc/cp/decl.c | 4 +++- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/cpp0x/enum15.C | 2 +- gcc/testsuite/g++.dg/cpp0x/enum28.C | 17 +++++++++++++++++ 7 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum28.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6dd0cd8dfbcb..502eecb812e1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2013-08-14 Paolo Carlini + + PR c++/51912 + * cp-tree.h (LOOKUP_NO_NON_INTEGRAL): Add. + * decl.c (case_conversion): Use it. + * call.c (standard_conversion): Likewise. + (implicit_conversion): Adjust. + 2013-08-13 Adam Butcher * pt.c: Grammar fix in comments ("it's" to "its"). diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 56346063f3db..e493a7947be5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1314,7 +1314,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, /* As an extension, allow conversion to complex type. */ else if (ARITHMETIC_TYPE_P (to)) { - if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE) + if (! (INTEGRAL_CODE_P (fcode) + || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL))) || SCOPED_ENUM_P (from)) return NULL; conv = build_conv (ck_std, to, conv); @@ -1681,7 +1682,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, resolution, or after we've chosen one. */ flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE - |LOOKUP_NO_NARROWING|LOOKUP_PROTECT); + |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL); /* FIXME: actually we don't want warnings either, but we can't just have 'complain &= ~(tf_warning|tf_error)' because it would cause diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 86727398fbc7..51dab8aa4f34 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4510,6 +4510,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; #define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1) /* Like LOOKUP_NO_TEMP_BIND, but also prevent binding to xvalues. */ #define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1) +/* Used by case_conversion to disregard non-integral conversions. */ +#define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 16f751c8ff12..95d5bbda785e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3103,7 +3103,9 @@ case_conversion (tree type, tree value) { if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type)) type = type_promotes_to (type); - value = perform_implicit_conversion (type, value, tf_warning_or_error); + value = (perform_implicit_conversion_flags + (type, value, tf_warning_or_error, + LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL)); } return cxx_constant_value (value); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72fcd6087ce2..9b115a48df31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-14 Paolo Carlini + + PR c++/51912 + * g++.dg/cpp0x/enum28.C: New. + * g++.dg/cpp0x/enum15.C: Adjust. + 2013-08-14 Bill Schmidt PR target/57949 diff --git a/gcc/testsuite/g++.dg/cpp0x/enum15.C b/gcc/testsuite/g++.dg/cpp0x/enum15.C index d653216498ed..1d33f90290f6 100644 --- a/gcc/testsuite/g++.dg/cpp0x/enum15.C +++ b/gcc/testsuite/g++.dg/cpp0x/enum15.C @@ -15,6 +15,6 @@ void foo (A a, int i) { case A::Val0: break; // { dg-error "" } case 1: break; - case 2.0: break; + case 2.0: break; // { dg-error "" } } } diff --git a/gcc/testsuite/g++.dg/cpp0x/enum28.C b/gcc/testsuite/g++.dg/cpp0x/enum28.C new file mode 100644 index 000000000000..3967699dd036 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum28.C @@ -0,0 +1,17 @@ +// PR c++/51912 +// { dg-do compile { target c++11 } } + +constexpr double g() { return 2.0; } + +void f(int i) +{ + switch (i) + { + case 1.0:; // { dg-error "could not convert" } + } + + switch (i) + { + case g():; // { dg-error "could not convert" } + } +} -- 2.47.2