From patchwork Mon Apr 11 21:47:24 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 90658 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id C74D6B6F12 for ; Tue, 12 Apr 2011 07:47:43 +1000 (EST) Received: (qmail 824 invoked by alias); 11 Apr 2011 21:47:41 -0000 Received: (qmail 806 invoked by uid 22791); 11 Apr 2011 21:47:38 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Apr 2011 21:47:26 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p3BLlPeI019174 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 11 Apr 2011 17:47:26 -0400 Received: from [127.0.0.1] ([10.3.113.3]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p3BLlOg4005275 for ; Mon, 11 Apr 2011 17:47:25 -0400 Message-ID: <4DA376EC.40908@redhat.com> Date: Mon, 11 Apr 2011 17:47:24 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.15) Gecko/20110307 Fedora/3.1.9-0.39.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.9 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/48457 (rvalue references and function lvalues) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 096fbbc..4d03646 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 3594ae4..d6b6197 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-func.C b/gcc/testsuite/g++.dg/cpp0x/rv-func.C new file mode 100644 index 0000000..db14296 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-func.C @@ -0,0 +1,22 @@ +// PR c++/48457, Core 1238 +// { dg-options -std=c++0x } + +template +T&& create(); + +template +void test() { + T t(create()); + (void) t; +} + +void f (void (&)()); +void f (void (&&)()); + +int main() { + test(); + test(); + // This call should choose the lvalue reference overload. + // { dg-final { scan-assembler-not "_Z1fOFvvE" } } + f(create()); +} diff --git a/libstdc++-v3/testsuite/20_util/is_convertible/value.cc b/libstdc++-v3/testsuite/20_util/is_convertible/value.cc index f6282a9..fc6007a 100644 --- a/libstdc++-v3/testsuite/20_util/is_convertible/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_convertible/value.cc @@ -93,7 +93,7 @@ void test01() const volatile int&>(false)) ); VERIFY( (test_relationship(false)) ); - VERIFY( (test_relationship(false)) ); + VERIFY( (test_relationship(true)) ); VERIFY( (test_relationship(false)) ); VERIFY( (test_relationship(false)) );