From patchwork Fri Mar 3 07:31:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 734967 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vZLTz1y5Rz9s7v for ; Fri, 3 Mar 2017 18:31:50 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="F9TueEyl"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; q=dns; s=default; b=ws1xqffIrbwgRH+dKD ywrfbgEVqO3FC9o7V3RiLNr1x8AbLyxvfisBzrt62+a9DehIsgQbB2jHpZxOCqsf vrmHEodQoMempfhCtSPRpN8tdBoos1qE5x/jJdodgjA9qleEwx96/JBYscFCJzGE ofaAC7zkM9UvEVbry+IybffDw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; s=default; bh=ETryNjcoA6xXTkJX9QMpY74r YPw=; b=F9TueEylawcIsUTlHgOdKESN4FGmJKUtGGfYjPRSJKWlF9FKoLrNAdRP ZHxapo1W3UYquNRi3P78kAd64od/p1fGpoUhW3jFA7evE/foMRWYlnoqhAGAOCxf mNl7dz1I/cXoFVyn4iR5KaXN5dCz2x+xL7WeXlZnbquJ3Aqy4hU= Received: (qmail 25253 invoked by alias); 3 Mar 2017 07:31:39 -0000 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 Received: (qmail 25239 invoked by uid 89); 3 Mar 2017 07:31:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.2 spammy= X-HELO: mail-ot0-f174.google.com Received: from mail-ot0-f174.google.com (HELO mail-ot0-f174.google.com) (74.125.82.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 03 Mar 2017 07:31:36 +0000 Received: by mail-ot0-f174.google.com with SMTP id k4so68440254otc.0 for ; Thu, 02 Mar 2017 23:31:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=cQd2rtrsLvgb0X2dcX8ghQFe4o+wyjqNQzRxx04ZOFI=; b=PiMLFliTYS1fZuHvTpnFvmD57wmGl/5PMLw1RYQrzS+g5C8UcRcegDRkPO4cylnmLw vZOS3GifzeR0kvfVTa+iCE/llCsx3wpIKHlUjFd0zeMRn7S2T2W2Q1u1RAOJjEKeXxE4 8ZG/8zIk+RRIX8yVo5iem7YtiIfMJhFyZ81+Azt2ZP6lzCEU4fbRybWS1pIZmPdKnVxI /IX+crmgB0apvMJ47Y1X4sCM7kVI8cEGMwYliu+DuyhhLqjhzF2BdZIi0POKFE8+wUga jI/lJryxjviXOiviRVF7T9gt2gV2adhl0l31XCcTbGIuI+0UBlLRpO/KwYdq1tYRSDJb K4Kg== X-Gm-Message-State: AMke39kOQJO/Z3WrpbzE+Qsqt/Enlf4j02nfWfn8P/bVe03vjSiWDxhb0vTGRJCqYyGdTkLLHtNKZnSItAnN5naM X-Received: by 10.157.43.9 with SMTP id o9mr710207otb.189.1488526295289; Thu, 02 Mar 2017 23:31:35 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.187.8 with HTTP; Thu, 2 Mar 2017 23:31:14 -0800 (PST) In-Reply-To: References: From: Jason Merrill Date: Thu, 2 Mar 2017 21:31:14 -1000 Message-ID: Subject: Re: C++ PATCH for C++17 class template argument deduction issues To: gcc-patches List X-IsSubscribed: yes On Thu, Mar 2, 2017 at 3:26 PM, Jason Merrill wrote: > On Wed, Mar 1, 2017 at 3:58 PM, Jason Merrill wrote: >> On Tue, Feb 28, 2017 at 1:56 PM, Jason Merrill wrote: >>> This patch implements some proposed resolutions to open issues with >>> C++17 class template argument deduction. >> >> And some more: > > This patch handles the issues of references to members of the class > template differently, by also allowing explicit guides to refer to > them: This patch adjusts some overload resolution. commit a777aadaf635dc1ef460c5e12d2ead4292eaa6a9 Author: Jason Merrill Date: Wed Mar 1 16:11:26 2017 -1000 Update overload resolution with deduction guides. * pt.c (do_class_deduction): Always build the copy guide. (copy_guide_p, template_guide_p): New. (build_deduction_guide): Remember the original constructor. * call.c (joust): Prefer the copy guide and non-template guides. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index babab00..dc629b96 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -9717,6 +9717,22 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, int art2 = DECL_ARTIFICIAL (cand2->fn); if (art1 != art2) return art2 - art1; + + if (art1) + { + /* Prefer the special copy guide over a declared copy/move + constructor. */ + if (copy_guide_p (cand1->fn)) + return 1; + if (copy_guide_p (cand2->fn)) + return -1; + + /* Prefer a candidate generated from a non-template constructor. */ + int tg1 = template_guide_p (cand1->fn); + int tg2 = template_guide_p (cand2->fn); + if (tg1 != tg2) + return tg2 - tg1; + } } /* or, if not that, F2 is from a using-declaration, F1 is not, and the diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 31edc5f..7583672 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6288,6 +6288,8 @@ extern tree template_parm_to_arg (tree); extern tree dguide_name (tree); extern bool dguide_name_p (tree); extern bool deduction_guide_p (const_tree); +extern bool copy_guide_p (const_tree); +extern bool template_guide_p (const_tree); /* in repo.c */ extern void init_repo (void); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3b320fc..13293eb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24852,6 +24852,35 @@ deduction_guide_p (const_tree fn) return false; } +/* True if FN is the copy deduction guide, i.e. A(A)->A. */ + +bool +copy_guide_p (const_tree fn) +{ + gcc_assert (deduction_guide_p (fn)); + if (!DECL_ARTIFICIAL (fn)) + return false; + tree parms = FUNCTION_FIRST_USER_PARMTYPE (DECL_TI_TEMPLATE (fn)); + return (TREE_CHAIN (parms) == void_list_node + && same_type_p (TREE_VALUE (parms), TREE_TYPE (DECL_NAME (fn)))); +} + +/* True if FN is a guide generated from a constructor template. */ + +bool +template_guide_p (const_tree fn) +{ + gcc_assert (deduction_guide_p (fn)); + if (!DECL_ARTIFICIAL (fn)) + return false; + if (tree ctor = DECL_ABSTRACT_ORIGIN (fn)) + { + tree tmpl = DECL_TI_TEMPLATE (ctor); + return PRIMARY_TEMPLATE_P (tmpl); + } + return false; +} + /* OLDDECL is a _DECL for a template parameter. Return a similar parameter at LEVEL:INDEX, using tsubst_args and complain for substitution into non-type template parameter types. Note that the handling of template template @@ -25100,6 +25129,8 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) TREE_TYPE (ded_tmpl) = TREE_TYPE (ded_fn); DECL_TEMPLATE_INFO (ded_fn) = build_template_info (ded_tmpl, targs); DECL_PRIMARY_TEMPLATE (ded_tmpl) = ded_tmpl; + if (DECL_P (ctor)) + DECL_ABSTRACT_ORIGIN (ded_fn) = ctor; if (ci) set_constraints (ded_tmpl, ci); @@ -25153,7 +25184,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, } bool saw_ctor = false; - bool saw_copy = false; if (CLASSTYPE_METHOD_VEC (type)) // FIXME cache artificial deduction guides for (tree fns = CLASSTYPE_CONSTRUCTORS (type); fns; fns = OVL_NEXT (fns)) @@ -25163,16 +25193,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, cands = ovl_cons (guide, cands); saw_ctor = true; - - tree parms = FUNCTION_FIRST_USER_PARMTYPE (fn); - if (parms && sufficient_parms_p (TREE_CHAIN (parms))) - { - tree pt = TREE_VALUE (parms); - if (TREE_CODE (pt) == REFERENCE_TYPE - && (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (pt), type))) - saw_copy = true; - } } if (!saw_ctor && args->length() == 0) @@ -25180,7 +25200,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init, int flags, tree guide = build_deduction_guide (type, outer_args, complain); cands = ovl_cons (guide, cands); } - if (!saw_copy && args->length() == 1) + if (args->length() == 1) { tree guide = build_deduction_guide (build_reference_type (type), outer_args, complain); diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction36.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction36.C new file mode 100644 index 0000000..129e29e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction36.C @@ -0,0 +1,15 @@ +// { dg-options -std=c++1z } + +template struct A { + A(T&); + A(const A&); +}; + +int i; +A a = i; +A a2 = a; + +template struct same; +template struct same {}; +same> s1; +same> s2; diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction38.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction38.C new file mode 100644 index 0000000..fe6c200 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction38.C @@ -0,0 +1,27 @@ +// { dg-options -std=c++1z } + +template struct A { + using value_type = T; + A(value_type); // #1 + A(const A&); // #2 + A(T, T, int); // #3 + template A(int, T, U); // #4 +}; // A(A); #5, the copy deduction candidate + +A x (1, 2, 3); // uses #3, generated from a non-template constructor + +template A(T) -> A; // #6, less specialized than #5 + +A a (42); // uses #6 to deduce A and #1 to initialize +A b = a; // uses #5 to deduce A and #2 to initialize + +template A(A) -> A>; // #7, as specialized as #5 + +A b2 = a; // uses #7 to deduce A> and #1 to initialize + +template struct same; +template struct same {}; + +same> s1; +same> s2; +same>> s3;