From patchwork Sat Feb 18 21:42:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 59028 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp562873wrn; Sat, 18 Feb 2023 13:44:16 -0800 (PST) X-Google-Smtp-Source: AK7set9eJ8mBN6Nar7EjKByEQJFllhvTIFboFnyxhSWRL8XEXHeFFu9jwGM3VrjLI/j4sGJe5vlH X-Received: by 2002:a17:907:2da8:b0:8b1:7274:1a72 with SMTP id gt40-20020a1709072da800b008b172741a72mr1569433ejc.6.1676756656661; Sat, 18 Feb 2023 13:44:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676756656; cv=none; d=google.com; s=arc-20160816; b=TQFocoev7tUaZzsPDqpGE5frdIQzGIL9oBxhWQVrmcABR9LUBJF5mIz6W9rMNg7Yd+ 4+X/1rS3nUzkEY3N6E8TejQjh3zD9ffa04k5GW/VZuobbCt6cmgL48khjPcAmqMkhBSL HU0xEJEOnRZZUsFFqXSkFHn7/s/mMbd+fqTbUYgXET3ckzMY4e8F5i5gqukQGdkOJ/Uq 7HIx5QGalrRYeLCxXGUmt9Kkc3IUztnXHm4QkmLG464YssvkrURhi5dJnWoGiq19/Apu EaAmqBDhD2NocUaLA5hSaIJPQggrhf4TLDiekEbdLhN2/Q3lP8e9R41DNbA5jDCPnCuf E8TA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=LDuDGnWt4jiH242VOFJTiIFnK0ySK+KnJBC9TFV27Qc=; b=b4hUY9K/gH5DgW2gR9BkEZ0LVZTfMdMZxKbDIuKPYI1go7Kp5vkGy2TFZinxYGXhiO iwzjMvCMa3/qvBL7QXBMwwBgcRyGRrqKXNvEtYriINPXwQ1ZKItGL2utg8nVV63xCuDc xbeIz72ngaEA7f3kRYORr4mFsPAaGC7X0w5fOnJ0CebzqQochABW+TLV1CRTPBLKtc5I HFAtiLArLi38XvyGbs2OZddbkla71py3k4627RfTl5lq+y4/3Uh7vEgmknfG2+zmGR/n fSjAmigOJAInjezodHs6Y84HQYlUS8eMG0j6utsBOB9Pp3wVWUFR9R7GLekJYx8m+cr3 7bwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=Yzd9jsJX; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ui4-20020a170907c90400b008b12d7f9788si8920269ejc.789.2023.02.18.13.44.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Feb 2023 13:44:16 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=Yzd9jsJX; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 086B9382E6BE for ; Sat, 18 Feb 2023 21:43:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 086B9382E6BE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1676756617; bh=LDuDGnWt4jiH242VOFJTiIFnK0ySK+KnJBC9TFV27Qc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Yzd9jsJXeqwZzxu63+WUJ9lXZfjUORwqowK4fe/umMY4biNuv1pQcVftirM4IXCWG ZO5Br/Yzb2llgbESi3Bp0AAMdPo6PNF4xaQd9W1bikDSThqL7SVke/KVTmQYz7XOky ToOcYYG+3C1JkmexxZf3MVxUsWlurCOEG8WYRJHE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 594743858D38 for ; Sat, 18 Feb 2023 21:42:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 594743858D38 Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-396-FZc183CgP9ekCj4ZDnNA1w-1; Sat, 18 Feb 2023 16:42:45 -0500 X-MC-Unique: FZc183CgP9ekCj4ZDnNA1w-1 Received: by mail-qt1-f200.google.com with SMTP id k17-20020ac86051000000b003b9a3ab9153so398562qtm.8 for ; Sat, 18 Feb 2023 13:42:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LDuDGnWt4jiH242VOFJTiIFnK0ySK+KnJBC9TFV27Qc=; b=tbfUIPlc6y2918Sp2y3eTNkhMnPIqQ14TOAdlb7XUfyp+nHQGviWh5TZa/EdtHd102 fV0/xvp8Qdz09VjvpYamxZhYt1XkKCa4NJNNX3S3IOKB7XZ583jQ+AnzDzMwPeL33ony 3oirIvDJZLBkLbolxapXy/ptixFP4EslcvJX1vRCoG8dP1CptE6CijzSwT0ySd9J1cL3 rOpHyl76FwFUdIam8sgSJEAhqIlmJJHTmmhogzTPfY50p0N3Mht/pbr9ga+XwoyYyGEX +7fh+UZ1SMuihKeJ93e55VUvVYpKoeTZlKXh6b8xLDOtr3uUlIY8CBdWiXX0pohyIZHL H81w== X-Gm-Message-State: AO0yUKXTwYlqqFQR6qhD6Cnp8F5VIyxE8bhygFBJ/F/7iVVZ0pEYvRBZ FZtTC+jjSQ4BDAKyGXMPuIXYYxCU/VBie36aYOQlwHioFNUfuvvJiyFrnrY9/AgRrqs3+BgxG86 kwWtwm6sM69h1NTvR7R3mvRnJ3EEhbURWgnk+kEIjGAg54qimgnhMzyreuWHNbXkEnbxT2vM= X-Received: by 2002:ac8:5f49:0:b0:3bd:1647:15cd with SMTP id y9-20020ac85f49000000b003bd164715cdmr12284629qta.2.1676756564767; Sat, 18 Feb 2023 13:42:44 -0800 (PST) X-Received: by 2002:ac8:5f49:0:b0:3bd:1647:15cd with SMTP id y9-20020ac85f49000000b003bd164715cdmr12284608qta.2.1676756564206; Sat, 18 Feb 2023 13:42:44 -0800 (PST) Received: from jason.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id u62-20020a372e41000000b0073d85e77fa9sm263717qkh.74.2023.02.18.13.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Feb 2023 13:42:43 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: Michael Spertus Subject: [PATCH 2/3] c++: fix alias CTAD [PR105841] Date: Sat, 18 Feb 2023 16:42:38 -0500 Message-Id: <20230218214239.2297623-2-jason@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230218214239.2297623-1-jason@redhat.com> References: <20230218214239.2297623-1-jason@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-24.9 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1758206788307932601?= X-GMAIL-MSGID: =?utf-8?q?1758206788307932601?= In my initial implementation of alias CTAD, I described a couple of differences from the specification that I thought would not have a practical effect; this testcase demonstrates that I was wrong. One difference is resolved by the CPTK_IS_DEDUCIBLE commit; the other (adding too many of the alias template parameters to the new deduction guide) is fixed by this patch. PR c++/105841 gcc/cp/ChangeLog: * pt.cc (corresponding_template_parameter_list): Split out... (corresponding_template_parameter): ...from here. (find_template_parameters): Factor out... (find_template_parameter_info::find_in): ...this function. (find_template_parameter_info::find_in_recursive): New. (find_template_parameter_info::found): New. (alias_ctad_tweaks): Only add parms used in the deduced args. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-alias14.C: New test. Co-authored-by: Michael Spertus --- gcc/cp/pt.cc | 133 +++++++++++++----- .../g++.dg/cpp2a/class-deduction-alias14.C | 13 ++ 2 files changed, 114 insertions(+), 32 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias14.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2aa06557b99..1934c9dafac 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10367,7 +10367,7 @@ lookup_and_finish_template_variable (tree templ, tree targs, return NULL_TREE. */ static tree -corresponding_template_parameter (tree parms, int level, int index) +corresponding_template_parameter_list (tree parms, int level, int index) { while (TMPL_PARMS_DEPTH (parms) > level) parms = TREE_CHAIN (parms); @@ -10376,7 +10376,30 @@ corresponding_template_parameter (tree parms, int level, int index) || TREE_VEC_LENGTH (TREE_VALUE (parms)) <= index) return NULL_TREE; - tree t = TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), index)); + return TREE_VEC_ELT (TREE_VALUE (parms), index); +} + +/* Return the TREE_LIST for the template parameter from PARMS that positionally + corresponds to the template parameter PARM, or else return NULL_TREE. */ + +static tree +corresponding_template_parameter_list (tree parms, tree parm) +{ + int level, index; + template_parm_level_and_index (parm, &level, &index); + return corresponding_template_parameter_list (parms, level, index); +} + +/* As above, but pull out the actual parameter. */ + +static tree +corresponding_template_parameter (tree parms, tree parm) +{ + tree list = corresponding_template_parameter_list (parms, parm); + if (!list) + return NULL_TREE; + + tree t = TREE_VALUE (list); /* As in template_parm_to_arg. */ if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL) t = TREE_TYPE (t); @@ -10386,18 +10409,6 @@ corresponding_template_parameter (tree parms, int level, int index) gcc_assert (TEMPLATE_PARM_P (t)); return t; } - -/* Return the template parameter from PARMS that positionally corresponds - to the template parameter PARM, or else return NULL_TREE. */ - -static tree -corresponding_template_parameter (tree parms, tree parm) -{ - int level, index; - template_parm_level_and_index (parm, &level, &index); - return corresponding_template_parameter (parms, level, index); -} - struct pair_fn_data { @@ -10670,6 +10681,11 @@ struct find_template_parameter_info tree *parm_list_tail = &parm_list; tree ctx_parms; int max_depth; + + tree find_in (tree); + tree find_in_recursive (tree); + bool found (tree); + unsigned num_found () { return parms.elements (); } }; /* Appends the declaration of T to the list in DATA. */ @@ -10812,6 +10828,52 @@ any_template_parm_r (tree t, void *data) return 0; } +/* Look through T for template parameters. */ + +tree +find_template_parameter_info::find_in (tree t) +{ + return for_each_template_parm (t, keep_template_parm, this, &visited, + /*include_nondeduced*/true, + any_template_parm_r); +} + +/* As above, but also recursively look into the default arguments of template + parameters we found. Used for alias CTAD. */ + +tree +find_template_parameter_info::find_in_recursive (tree t) +{ + if (tree r = find_in (t)) + return r; + /* Since newly found parms are added to the end of the list, we + can just walk it until we reach the end. */ + for (tree pl = parm_list; pl; pl = TREE_CHAIN (pl)) + { + tree parm = TREE_VALUE (pl); + tree list = corresponding_template_parameter_list (ctx_parms, parm); + if (tree r = find_in (TREE_PURPOSE (list))) + return r; + } + return NULL_TREE; +} + +/* True if PARM was found by a previous call to find_in. PARM can be a + TREE_LIST, a DECL_TEMPLATE_PARM_P, or a TEMPLATE_PARM_P. */ + +bool +find_template_parameter_info::found (tree parm) +{ + if (TREE_CODE (parm) == TREE_LIST) + parm = TREE_VALUE (parm); + if (TREE_CODE (parm) == TYPE_DECL) + parm = TREE_TYPE (parm); + else + parm = DECL_INITIAL (parm); + gcc_checking_assert (TEMPLATE_PARM_P (parm)); + return parms.contains (parm); +} + /* Returns a list of unique template parameters found within T, where CTX_PARMS are the template parameters in scope. */ @@ -10822,8 +10884,7 @@ find_template_parameters (tree t, tree ctx_parms) return NULL_TREE; find_template_parameter_info ftpi (ctx_parms); - for_each_template_parm (t, keep_template_parm, &ftpi, &ftpi.visited, - /*include_nondeduced*/true, any_template_parm_r); + ftpi.find_in (t); return ftpi.parm_list; } @@ -29977,22 +30038,11 @@ alias_ctad_tweaks (tree tmpl, tree uguides) * The explicit-specifier of f' is the explicit-specifier of g (if any). */ - /* This implementation differs from the above in two significant ways: - - 1) We include all template parameters of A, not just some. - 2) [fixed] The added constraint is same_type instead of deducible. - - I believe that while it's probably possible to construct a testcase that - behaves differently with this simplification, it should have the same - effect for real uses. Including all template parameters means that we - deduce all parameters of A when resolving the call, so when we're in the - constraint we don't need to deduce them again, we can just check whether - the deduction produced the desired result. */ - tsubst_flags_t complain = tf_warning_or_error; tree atype = TREE_TYPE (tmpl); tree aguides = NULL_TREE; - tree atparms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); + tree fullatparms = DECL_TEMPLATE_PARMS (tmpl); + tree atparms = INNERMOST_TEMPLATE_PARMS (fullatparms); unsigned natparms = TREE_VEC_LENGTH (atparms); tree utype = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); for (ovl_iterator iter (uguides); iter; ++iter) @@ -30022,16 +30072,27 @@ alias_ctad_tweaks (tree tmpl, tree uguides) for (unsigned i = 0; i < len; ++i) if (TREE_VEC_ELT (targs, i) == NULL_TREE) ++ndlen; - tree gtparms = make_tree_vec (natparms + ndlen); + find_template_parameter_info ftpi (fullatparms); + ftpi.find_in_recursive (targs); + unsigned nusedatparms = ftpi.num_found (); + unsigned nfparms = nusedatparms + ndlen; + tree gtparms = make_tree_vec (nfparms); /* Set current_template_parms as in build_deduction_guide. */ auto ctp = make_temp_override (current_template_parms); current_template_parms = copy_node (DECL_TEMPLATE_PARMS (tmpl)); TREE_VALUE (current_template_parms) = gtparms; + j = 0; /* First copy over the parms of A. */ - for (j = 0; j < natparms; ++j) - TREE_VEC_ELT (gtparms, j) = TREE_VEC_ELT (atparms, j); + for (unsigned i = 0; i < natparms; ++i) + { + tree elt = TREE_VEC_ELT (atparms, i); + if (ftpi.found (elt)) + TREE_VEC_ELT (gtparms, j++) = elt; + } + gcc_checking_assert (j == nusedatparms); + /* Now rewrite the non-deduced parms of f. */ for (unsigned i = 0; ndlen && i < len; ++i) if (TREE_VEC_ELT (targs, i) == NULL_TREE) @@ -30058,6 +30119,13 @@ alias_ctad_tweaks (tree tmpl, tree uguides) } if (g == error_mark_node) continue; + if (nfparms == 0) + { + /* The targs are all non-dependent, so g isn't a template. */ + fprime = g; + ret = TREE_TYPE (TREE_TYPE (fprime)); + goto non_template; + } DECL_USE_TEMPLATE (g) = 0; fprime = build_template_decl (g, gtparms, false); DECL_TEMPLATE_RESULT (fprime) = g; @@ -30094,6 +30162,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides) { /* For a non-template deduction guide, if the arguments of A aren't deducible from the return type, don't add the candidate. */ + non_template: if (!type_targs_deducible_from (tmpl, ret)) continue; } diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias14.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias14.C new file mode 100644 index 00000000000..22b96bcd5d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias14.C @@ -0,0 +1,13 @@ +// PR c++/105841 +// { dg-do compile { target c++20 } } + +template +struct A { A(...); }; + +template +A(T, Ts...) -> A; + +template +using B = A; + +B b(0, 0);