From patchwork Wed Nov 17 01:40:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 71502 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 46181B715D for ; Wed, 17 Nov 2010 12:40:32 +1100 (EST) Received: (qmail 17003 invoked by alias); 17 Nov 2010 01:40:31 -0000 Received: (qmail 16994 invoked by uid 22791); 17 Nov 2010 01:40:29 -0000 X-SWARE-Spam-Status: No, hits=-6.1 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; Wed, 17 Nov 2010 01:40:24 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oAH1eLDJ014870 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 16 Nov 2010 20:40:22 -0500 Received: from [127.0.0.1] (ovpn-113-96.phx2.redhat.com [10.3.113.96]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oAH1eKom029917; Tue, 16 Nov 2010 20:40:20 -0500 Message-ID: <4CE33283.5070500@redhat.com> Date: Tue, 16 Nov 2010 20:40:19 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101114 Lightning/1.0b1 Shredder/3.0.11pre MIME-Version: 1.0 To: gcc-patches List , Paolo Carlini Subject: C++ PATCH for c++/46497 (is_convertible failure with defaulted move ctor) 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 This bug was hard to track down; it took me a long time to figure out what could have been the difference between cases that worked and cases that didn't. Finally I realized that we were rejecting a deleted trivial move constructor in SFINAE context, but allowing it in normal context. Fixed so we reject it consistently. The second patch is a related case I noticed: It seems we would (incorrectly) reject copy-list-initialization involving a trivial deleted constructor in SFINAE context but (correctly) accept it in normal context. Fixed by moving the special handling into convert_like_real. The error handling change fixes a wrong "incomplete type" error for a class that is currently being defined. Tested x86_64-pc-linux-gnu, applied to trunk. commit 3441224d830415e3d7b907340addde2c2efcf123 Author: Jason Merrill Date: Tue Nov 16 14:47:49 2010 -0500 PR c++/46497 * call.c (build_over_call): Check for =delete even when trivial. commit 4796a6c672241f2887369e758e8ebc24a3a1ade5 Author: Jason Merrill Date: Tue Nov 16 19:56:52 2010 -0500 * call.c (convert_like_real): Don't make a temp for copy-list-init. (build_over_call): Don't handle that here. (build_new_method_call): Use COMPLETE_OR_OPEN_TYPE_P for error. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7fa1cf6..5e74bd2 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5290,6 +5290,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, conversion (i.e. the second step of copy-initialization), so don't allow any more. */ flags |= LOOKUP_NO_CONVERSION; + if (TREE_CODE (expr) == TARGET_EXPR + && TARGET_EXPR_LIST_INIT_P (expr)) + /* Copy-list-initialization doesn't actually involve a copy. */ + return expr; expr = build_temp (expr, totype, flags, &diag_kind, complain); if (diag_kind && fn) { @@ -6049,15 +6053,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) else arg = cp_build_indirect_ref (arg, RO_NULL, complain); - if (TREE_CODE (arg) == TARGET_EXPR - && TARGET_EXPR_LIST_INIT_P (arg)) - { - /* Copy-list-initialization doesn't require the constructor - to be defined. */ - } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - else if (!trivial || DECL_DELETED_FN (fn)) + if (!trivial || DECL_DELETED_FN (fn)) { mark_used (fn); already_used = true; @@ -6641,7 +6639,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, { if (complain & tf_error) { - if (!COMPLETE_TYPE_P (basetype)) + if (!COMPLETE_OR_OPEN_TYPE_P (basetype)) cxx_incomplete_type_error (instance_ptr, basetype); else if (optype) error ("no matching function for call to %<%T::operator %T(%A)%#V%>", diff --git a/gcc/cp/call.c b/gcc/cp/call.c index eb7247d..7fa1cf6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6057,7 +6057,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } /* [class.copy]: the copy constructor is implicitly defined even if the implementation elided its use. */ - else if (!trivial) + else if (!trivial || DECL_DELETED_FN (fn)) { mark_used (fn); already_used = true; @@ -6086,7 +6086,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) } } else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR - && trivial_fn_p (fn)) + && trivial_fn_p (fn) + && !DECL_DELETED_FN (fn)) { tree to = stabilize_reference (cp_build_indirect_ref (argarray[0], RO_NULL, complain)); diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted20.C b/gcc/testsuite/g++.dg/cpp0x/defaulted20.C new file mode 100644 index 0000000..d9ad04f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/defaulted20.C @@ -0,0 +1,19 @@ +// PR c++/46497 +// { dg-options -std=c++0x } + +struct A { + A(A&&) = default; // { dg-message "A::A" } +}; +struct B { + const A a; + B(const B&) = default; + B(B&&) = default; // { dg-error "implicitly deleted|no match" } +}; + +void g(B); // { dg-error "argument 1" } +B&& f(); + +int main() +{ + g(f()); // { dg-error "deleted" } +}