re PR c++/49105 ([C++0x][SFINAE] ICE during list-initialization of rvalue-references...
authorJason Merrill <jason@redhat.com>
Mon, 23 May 2011 22:56:04 +0000 (18:56 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 23 May 2011 22:56:04 +0000 (18:56 -0400)
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
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/sfinae25.C [new file with mode: 0644]

index 2a4ffe09cd88e1df6fa7e50715096627db27c768..032c8e23475b3bb2982db2c0c8da06b128d1ed55 100644 (file)
@@ -1,5 +1,10 @@
 2011-05-23  Jason Merrill  <jason@redhat.com>
 
+       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.
 
index 13b919ca37ffe25c99c0ca7c00360d4665a51e7b..69b25d39645405acd9e72809537a854ad6ac927e 100644 (file)
@@ -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)));
     }
 
-  /* "Alvalue 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
index ea4466c54edb7c74900d9fbbc3fbe26b9f637ead..f58dea33569ef399408b5518012e72ee42ecf679 100644 (file)
@@ -1,5 +1,7 @@
 2011-05-23  Jason Merrill  <jason@redhat.com>
 
+       * 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 (file)
index 0000000..7bdc8f8
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/49105
+// { dg-options -std=c++0x }
+
+template<class T, class = decltype(T{})>
+char f(int);
+
+template<class T>
+auto f(...) -> char(&)[2];
+
+static_assert(sizeof(f<const int&&>(0)) == 1, "Error"); // #