From 8e3fb544446fca2bcdc68618b36cd3d3b2cf46c5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 23 May 2011 18:56:04 -0400 Subject: [PATCH] re PR c++/49105 ([C++0x][SFINAE] ICE during list-initialization of rvalue-references to const) PR c++/49105 * typeck.c (cp_build_c_cast): Don't strip cv-quals when converting to reference. (build_static_cast_1): Update for glvalues. From-SVN: r174093 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/typeck.c | 6 +++--- gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/g++.dg/cpp0x/sfinae25.C | 10 ++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/sfinae25.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2a4ffe09cd8..032c8e23475 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2011-05-23 Jason Merrill + PR c++/49105 + * typeck.c (cp_build_c_cast): Don't strip cv-quals when + converting to reference. + (build_static_cast_1): Update for glvalues. + PR c++/49105 * typeck.c (build_const_cast_1): Handle rvalue references. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 13b919ca37f..69b25d39645 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5768,11 +5768,11 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p, return convert_from_reference (rvalue (cp_fold_convert (type, expr))); } - /* "An lvalue of type cv1 T1 can be cast to type rvalue reference to + /* "A glvalue of type cv1 T1 can be cast to type rvalue reference to cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)." */ if (TREE_CODE (type) == REFERENCE_TYPE && TYPE_REF_IS_RVALUE (type) - && real_lvalue_p (expr) + && lvalue_or_rvalue_with_address_p (expr) && reference_related_p (TREE_TYPE (type), intype) && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype))) { @@ -6448,7 +6448,7 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain) if (!CLASS_TYPE_P (type)) type = TYPE_MAIN_VARIANT (type); result_type = TREE_TYPE (result); - if (!CLASS_TYPE_P (result_type)) + if (!CLASS_TYPE_P (result_type) && TREE_CODE (type) != REFERENCE_TYPE) result_type = TYPE_MAIN_VARIANT (result_type); /* If the type of RESULT does not match TYPE, perform a const_cast to make it match. If the static_cast or diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea4466c54ed..f58dea33569 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-05-23 Jason Merrill + * g++.dg/cpp0x/sfinae25.C: New. + * g++.dg/cpp0x/rv-cast2.C: New. * g++.dg/cpp0x/enum14.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae25.C b/gcc/testsuite/g++.dg/cpp0x/sfinae25.C new file mode 100644 index 00000000000..7bdc8f88e51 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae25.C @@ -0,0 +1,10 @@ +// PR c++/49105 +// { dg-options -std=c++0x } + +template +char f(int); + +template +auto f(...) -> char(&)[2]; + +static_assert(sizeof(f(0)) == 1, "Error"); // # -- 2.30.2