From patchwork Mon Sep 26 18:00:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 116463 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 BCBD5B6F65 for ; Tue, 27 Sep 2011 04:00:39 +1000 (EST) Received: (qmail 25523 invoked by alias); 26 Sep 2011 18:00:33 -0000 Received: (qmail 25511 invoked by uid 22791); 26 Sep 2011 18:00:31 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS 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, 26 Sep 2011 18:00:11 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p8QI0AhQ022046 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 26 Sep 2011 14:00:10 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p8QI0Afd013956 for ; Mon, 26 Sep 2011 14:00:10 -0400 Received: from [0.0.0.0] ([10.3.113.13]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p8QI08nm016642 for ; Mon, 26 Sep 2011 14:00:09 -0400 Message-ID: <4E80BDA3.2030301@redhat.com> Date: Mon, 26 Sep 2011 14:00:03 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0.2) Gecko/20110906 Thunderbird/6.0.2 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/50512 (regression in overload resolution) 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 My patch for DR 1328 started comparing rvaluedness_matches_p for all reference binding conversions, not just those where the target type differs in rvaluedness. In this testcase, the rvaluedness of the initializer differs: when calling the first function the initializer is a pointer constant, while with the second one the initializer is an array lvalue. This patch avoids preferring the second by limiting the rvaluedness match test to either cases where the target type differs in rvaluedness or is the same. Tested x86_64-pc-linux-gnu, applied to trunk. commit a745b69ecfdad74c803282e29749c4deec416a3f Author: Jason Merrill Date: Mon Sep 26 13:36:57 2011 -0400 PR c++/50512 * call.c (compare_ics): Only consider rvaluedness_matches_p if the target type is the same or it too differs in rvalueness. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 579e563..a52ec29 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7864,18 +7864,25 @@ compare_ics (conversion *ics1, conversion *ics2) types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to - which the reference initialized by S1 refers */ + which the reference initialized by S1 refers. + + DR 1328 [over.match.best]: the context is an initialization by + conversion function for direct reference binding (13.3.1.6) of a + reference to function type, the return type of F1 is the same kind of + reference (i.e. lvalue or rvalue) as the reference being initialized, + and the return type of F2 is not. */ if (ref_conv1 && ref_conv2) { - if (!ref_conv1->this_p && !ref_conv2->this_p) + if (!ref_conv1->this_p && !ref_conv2->this_p + && (ref_conv1->rvaluedness_matches_p + != ref_conv2->rvaluedness_matches_p) + && (same_type_p (ref_conv1->type, ref_conv2->type) + || (TYPE_REF_IS_RVALUE (ref_conv1->type) + != TYPE_REF_IS_RVALUE (ref_conv2->type)))) { - if (ref_conv1->rvaluedness_matches_p - > ref_conv2->rvaluedness_matches_p) - return 1; - if (ref_conv2->rvaluedness_matches_p - > ref_conv1->rvaluedness_matches_p) - return -1; + return (ref_conv1->rvaluedness_matches_p + - ref_conv2->rvaluedness_matches_p); } if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2)) diff --git a/gcc/testsuite/g++.dg/overload/rvalue3.C b/gcc/testsuite/g++.dg/overload/rvalue3.C new file mode 100644 index 0000000..5a5d237 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/rvalue3.C @@ -0,0 +1,8 @@ +// PR c++/50512 + +void foo (const char *const& s); +template void foo (const C& x) { x.a; } + +void f () { + foo ("abc"); +}