Comments
Patch
@@ -1521,8 +1521,10 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
actually occurs. */
conv->need_temporary_p = true;
- /* Don't allow binding of lvalues to rvalue references. */
+ /* Don't allow binding of lvalues (other than function lvalues) to
+ rvalue references. */
if (is_lvalue && TYPE_REF_IS_RVALUE (rto)
+ && TREE_CODE (to) != FUNCTION_TYPE
&& !(flags & LOOKUP_PREFER_RVALUE))
conv->bad_p = true;
@@ -73,7 +73,9 @@ lvalue_kind (const_tree ref)
if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref))
&& TREE_CODE (ref) != PARM_DECL
&& TREE_CODE (ref) != VAR_DECL
- && TREE_CODE (ref) != COMPONENT_REF)
+ && TREE_CODE (ref) != COMPONENT_REF
+ /* Functions are always lvalues. */
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (ref))) != FUNCTION_TYPE)
return clk_rvalueref;
/* lvalue references and named rvalue references are lvalues. */
new file mode 100644
@@ -0,0 +1,22 @@
+// PR c++/48457, Core 1238
+// { dg-options -std=c++0x }
+
+template<class T>
+T&& create();
+
+template<class T, class Arg>
+void test() {
+ T t(create<Arg>());
+ (void) t;
+}
+
+void f (void (&)());
+void f (void (&&)());
+
+int main() {
+ test<void(&)(), void()>();
+ test<void(&&)(), void()>();
+ // This call should choose the lvalue reference overload.
+ // { dg-final { scan-assembler-not "_Z1fOFvvE" } }
+ f(create<void()>());
+}
@@ -93,7 +93,7 @@ void test01()
const volatile int&>(false)) );
VERIFY( (test_relationship<is_convertible, volatile int,
volatile int&>(false)) );
- VERIFY( (test_relationship<is_convertible, int(int), int(&)(int)>(false)) );
+ VERIFY( (test_relationship<is_convertible, int(int), int(&)(int)>(true)) );
VERIFY( (test_relationship<is_convertible, int&, ExplicitClass>(false)) );
VERIFY( (test_relationship<is_convertible, void*, ExplicitClass>(false)) );
Recent discussion of how to deal with rvalue references and functions ended with the decision that an expression of function type is always an lvalue, even if it is derived from an rvalue reference, but that rvalue references can bind to function lvalues. Tested x86_64-pc-linux-gnu, applying to trunk. commit dcc37da352dd87c5f2f1f103c9794effa180e43d Author: Jason Merrill <jason@redhat.com> Date: Fri Apr 8 18:55:21 2011 -0400 PR c++/48457, Core 1238 * call.c (reference_binding): Allow rvalue reference to bind to function lvalue. * tree.c (lvalue_kind): Functions are always lvalues.