PR c++/48457, Core 1238
authorJason Merrill <jason@redhat.com>
Mon, 11 Apr 2011 22:00:06 +0000 (18:00 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 11 Apr 2011 22:00:06 +0000 (18:00 -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.

From-SVN: r172282

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/rv-func.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/20_util/is_convertible/value.cc

index 1b8f87363af82d8634686a648e1242a7703582aa..104005169650a75792d6ed5e8d43e063eea3c730 100644 (file)
@@ -1,3 +1,10 @@
+2011-04-11  Jason Merrill  <jason@redhat.com>
+
+       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.
+
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
        PR c++/48500
index 096fbbc3d9c4998ae8f26a057db9cc5656123d66..4d03646b44421f9b270742e0039e44a2d4f7680e 100644 (file)
@@ -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;
 
index 3594ae42dd5467074a7efbb408acf166f6531c5d..d6b6197cbe23e9d4ec33aa98f6b1e4c8363c5069 100644 (file)
@@ -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.  */
index dee6793d9316ad876c9de5e315d23b2e508b5163..3812feff89a3ee922412012271ff95f77b65f696 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-11  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/rv-func.C: New.
+
 2011-04-11  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * gcc.dg/torture/pr47917.c: Define _ISO_C_SOURCE=19990L for
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-func.C b/gcc/testsuite/g++.dg/cpp0x/rv-func.C
new file mode 100644 (file)
index 0000000..db14296
--- /dev/null
@@ -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()>());
+}
index c4ed61f53762f3dd73c26c1e940a8da68b40d51f..5768ea607080481d78ff5aa24d7d1d7cf10598ad 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-08  Jason Merrill  <jason@redhat.com>
+
+       * testsuite/20_util/is_convertible/value.cc: Adjust.
+
 2011-04-11  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * testsuite/25_algorithms/inplace_merge/moveable.cc: Actually run
index f6282a9019691c16e8c0249fa49108b78314f77d..fc6007ac55593058bece6db5b478fd797a422de9 100644 (file)
@@ -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)) );