From patchwork Wed May 8 17:49:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1933144 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Qg2mbeCY; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VZN2H55sGz1ymg for ; Thu, 9 May 2024 03:49:43 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 91BA4384AB64 for ; Wed, 8 May 2024 17:49:41 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 51EBD3858C50 for ; Wed, 8 May 2024 17:49:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 51EBD3858C50 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 51EBD3858C50 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715190559; cv=none; b=xx5V8NiSOclpLJjLcb+3p/8s9luexUW4oZ5gEpneIvwBnSEkH5ij6YqaZOPZeSP75Zp/eZCipqDZ59La13j/YrI6dUKYApKTCuH0KyexV+ZMtaJu4bb4IxqNNxkfrQ5CkSDKN65/WZ3F7+sRexcGcsxGdcGF6QY+3IBW6QWq76Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715190559; c=relaxed/simple; bh=+Qe1eS0EhRT4qeXy7JPiE9mhHonc/G384Uk9ZSjfvEw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=X54qpNknLbNEopYZpljvCK/ZWPluTmXa4HrHXfq4Mh+eBdW0721JnLt0k7v5zmAkyBnJclim1ChhT+vDk5ThxIrd1kf4jHA6IHQrGZs/xQPsk1QgnXhQ9nMoq+yS0dD5CMiTenQYyBCHOeQ2S32CKYGf/tOr4w0hgNXXcTaT37g= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715190557; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=r+vuaCnV+F3fLrCGQph8YwTQt949aSs2l48gsjow2GA=; b=Qg2mbeCY9XitQD6VwaRlawkftxJIsecMNN6FHiyLoCOcBVOpPV5iJQMwAnHyW2F5teAuHX 0dNQMm4XXLRlUlA98R8sUnhxaiAvv0lYS2UbvGgRUrWAwTRfRwmqNeOMoCjNdOxy0NhhFp tCbPE2tzAyzdU6Dqw980+0XFFcCHBO8= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-661-FreMfb12PW-MAQCbQN5VZQ-1; Wed, 08 May 2024 13:49:15 -0400 X-MC-Unique: FreMfb12PW-MAQCbQN5VZQ-1 Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-6a0b7ebba6cso812686d6.0 for ; Wed, 08 May 2024 10:49:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715190554; x=1715795354; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=r+vuaCnV+F3fLrCGQph8YwTQt949aSs2l48gsjow2GA=; b=A/gtQZRtxuDwgDr914cKtxJjTkQWuGa7qk9mweHHxAF77xWZOzin6BUsUtdagS/Pw9 QVYz3QrfMHewWZFBA9TC6DqnT12zdTbPAXWR3freiTtG+/gWGVrZogxFGpokrCYO77RL b9eKs8FOjP1jRTf8etL/T2pPJtJsJsjJ6I0gnbVyXXmlfIGTAqlwMsATrm7AETpxG7Hu 8cMGQ1bQmUDoD0NU8Eplrd21QMLgjrx5e6B0xeOoTS92q14NFGtpUptEtdMB2/lMeyqt aA77HpR9b8+39+aiV9GBWm2i+rlzX4jmSuOywmbSmK7buTKCOmM9wz/LYNxuZiuTM8O8 eOng== X-Gm-Message-State: AOJu0Yx43hdMIWSkJ8s21EoDMGlmOlHAagGZvLGwRbiI/lui5ZduI4Lw T1I/SAAlLyiiUh0zlnVLdpGVdaBvnCpooo8LxJKjVL+ER+cDQBoZLhQivsE+cYvo8eLdrw106Hr yoNKK6pInMppVuBojP9EmfMn5iXjktaqBwZqSKt/ro/NLNMZe+SCOnW4nb0u0OlOmwTqHxYWjZO 4T3ppQz97aYglCEDwCLQ9j23rieIA+uTe+radj X-Received: by 2002:a05:6214:4001:b0:6a0:ab58:7f52 with SMTP id 6a1803df08f44-6a1514fec9amr35659406d6.37.1715190554445; Wed, 08 May 2024 10:49:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGVt7dq39fwLecLPz1pi56t+YiwiqOCKVZ+OxfjiW7fu7bc0i/KButBnp/q2DF/Gh/EikY2YQ== X-Received: by 2002:a05:6214:4001:b0:6a0:ab58:7f52 with SMTP id 6a1803df08f44-6a1514fec9amr35659166d6.37.1715190553941; Wed, 08 May 2024 10:49:13 -0700 (PDT) Received: from localhost.localdomain (ool-18bb2a2e.dyn.optonline.net. [24.187.42.46]) by smtp.gmail.com with ESMTPSA id qb17-20020ad44711000000b006a0e585dc77sm5736976qvb.70.2024.05.08.10.49.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 May 2024 10:49:13 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: nested aggregate/alias CTAD fixes Date: Wed, 8 May 2024 13:49:11 -0400 Message-ID: <20240508174911.1278083-1-ppalka@redhat.com> X-Mailer: git-send-email 2.45.0.31.gd4cc1ec35f MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, RCVD_IN_SORBS_WEB, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped and regtested on x86-64-pc-linux-gnu, does this look OK for trunk and perhaps 14? -- >8 -- During maybe_aggr_guide with a nested class template and paren init, like with list init we need to consider the generic template type rather than the partially instantiated type since only the former has TYPE_FIELDS. And in turn we need to partially substitute PARMs in the paren init case as well. As a drive-by improvement it seems better to use outer_template_args instead of DECL_TI_ARGS during this partial substitution so that we lower instead of substitute the innermost generic template arguments, which is generally more robust. And during alias_ctad_tweaks with a nested class template, even though the guides may be already partially instantiated we still need to use the full set of arguments, not just the innermost, when substituting its constraints. PR c++/114974 PR c++/114901 PR c++/114903 gcc/cp/ChangeLog: * pt.cc (maybe_aggr_guide): Fix obtaining TYPE_FIELDS in the paren init case. Hoist out partial substitution logic to apply to the paren init case as well. (alias_ctad_tweaks): Substitute constraints using the full set of template arguments. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/class-deduction-aggr14.C: New test. * g++.dg/cpp2a/class-deduction-alias20.C: New test. * g++.dg/cpp2a/class-deduction-alias21.C: New test. --- gcc/cp/pt.cc | 39 +++++++++++-------- .../g++.dg/cpp2a/class-deduction-aggr14.C | 11 ++++++ .../g++.dg/cpp2a/class-deduction-alias20.C | 22 +++++++++++ .../g++.dg/cpp2a/class-deduction-alias21.C | 38 ++++++++++++++++++ 4 files changed, 93 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr14.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias20.C create mode 100644 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias21.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 1816bfd1f40..f3d52acaaac 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -30192,26 +30192,11 @@ maybe_aggr_guide (tree tmpl, tree init, vec *args) if (init == error_mark_node) return NULL_TREE; parms = collect_ctor_idx_types (init, parms); - /* If we're creating a deduction guide for a member class template, - we've used the original template pattern type for the reshape_init - above; this is done because we want PARMS to be a template parameter - type, something that can be deduced when used as a function template - parameter. At this point the outer class template has already been - partially instantiated (we deferred the deduction until the enclosing - scope is non-dependent). Therefore we have to partially instantiate - PARMS, so that its template level is properly reduced and we don't get - mismatches when deducing types using the guide with PARMS. */ - if (member_template_p) - { - ++processing_template_decl; - parms = tsubst (parms, DECL_TI_ARGS (tmpl), complain, init); - --processing_template_decl; - } } else if (TREE_CODE (init) == TREE_LIST) { int len = list_length (init); - for (tree field = TYPE_FIELDS (type); + for (tree field = TYPE_FIELDS (template_type); len; --len, field = DECL_CHAIN (field)) { @@ -30226,6 +30211,22 @@ maybe_aggr_guide (tree tmpl, tree init, vec *args) /* Aggregate initialization doesn't apply to an initializer expression. */ return NULL_TREE; + /* If we're creating a deduction guide for a member class template, + we've used the original template pattern type for the reshape_init + above; this is done because we want PARMS to be a template parameter + type, something that can be deduced when used as a function template + parameter. At this point the outer class template has already been + partially instantiated (we deferred the deduction until the enclosing + scope is non-dependent). Therefore we have to partially instantiate + PARMS, so that its template level is properly reduced and we don't get + mismatches when deducing types using the guide with PARMS. */ + if (member_template_p) + { + ++processing_template_decl; + parms = tsubst (parms, outer_template_args (tmpl), complain, init); + --processing_template_decl; + } + if (parms) { tree last = parms; @@ -30417,7 +30418,11 @@ alias_ctad_tweaks (tree tmpl, tree uguides) /* Substitute the associated constraints. */ tree ci = get_constraints (f); if (ci) - ci = tsubst_constraint_info (ci, targs, complain, in_decl); + { + if (tree outer_targs = outer_template_args (f)) + ci = tsubst_constraint_info (ci, outer_targs, complain, in_decl); + ci = tsubst_constraint_info (ci, targs, complain, in_decl); + } if (ci == error_mark_node) continue; diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr14.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr14.C new file mode 100644 index 00000000000..68786652502 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-aggr14.C @@ -0,0 +1,11 @@ +// PR c++/114974 +// { dg-do compile { target c++20 } } + +template +struct A { + template + struct B { T2 t; }; +}; + +A::B x{2}; // OK +A::B y(2); // previously rejected diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias20.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias20.C new file mode 100644 index 00000000000..8cc56d91e37 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias20.C @@ -0,0 +1,22 @@ +// PR c++/114901 +// { dg-do compile { target c++20 } } + +template +constexpr bool C = sizeof(D); + +template +struct T { + template + struct Foo { + Foo(V, N); + }; + + template + requires (C) // removes the require-clause will make the crash disappear + Foo(X, N) -> Foo; + + template + using AFoo = Foo; +}; + +T::AFoo s{1, 2}; // { dg-error "deduction|no match" } diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias21.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias21.C new file mode 100644 index 00000000000..c39a0f9f141 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias21.C @@ -0,0 +1,38 @@ +// PR c++/114903 +// { dg-do compile { target c++20 } } + +template +struct Key { + Key(int); +}; + +class Forward {}; + +template +constexpr bool C = __is_same(T, Forward); + +template +struct Outer { + template + struct Foo { + Foo(U); + U u; + }; + + template + requires(C) + Foo(V) -> Foo; +}; + +template +struct T { + template + struct T2 { + template + using AFoo = Outer::template Foo; + }; +}; + +T::T2::AFoo a(1.0); +using type = decltype(a); +using type = Outer::Foo;