From patchwork Wed Sep 21 16:16:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1680774 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=moTl9WB+; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MXk8j4fJPz1yqK for ; Thu, 22 Sep 2022 02:17:40 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D64B53858421 for ; Wed, 21 Sep 2022 16:17:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D64B53858421 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663777056; bh=yIWwX4AQhFHqzPXtZ68+cj/vMpJgHVoP+cpqKuUjrys=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=moTl9WB+w85d8DOAnCeiMZM4Dr3k7UmDSXfjCyfzPKT2WK8Xgrd9G7itVZXwWIj9V qTjyuEEZXF9+x4UOqg6u9eWp+DxPJEgaUEEjCHqp9DMKz5DF92kQKl6LUSQC+uoBkC tDqNhq/HN3Q8F+u77v8fpA5jkAdmZMIJDy/vNtdc= 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 DDD603858CDB for ; Wed, 21 Sep 2022 16:17:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DDD603858CDB 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-637-YEwOKQgXNbms7grCJRIERg-1; Wed, 21 Sep 2022 12:17:12 -0400 X-MC-Unique: YEwOKQgXNbms7grCJRIERg-1 Received: by mail-qt1-f200.google.com with SMTP id e8-20020ac85988000000b0035c39dd5eb9so4512333qte.16 for ; Wed, 21 Sep 2022 09:17:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date; bh=yIWwX4AQhFHqzPXtZ68+cj/vMpJgHVoP+cpqKuUjrys=; b=S7CZxf1BH4MQH+mtSgL9WOoB5Nhfi4f32izZGY6n+iISyB7wjmarSHL1KAllmtT5Ai kXFnB8jc8X1qntTMGp86S19z9pwM3FHTrEx0/tCc51HcY+JrVIDZIz3m/IsdY/0DlLgN ge7rfLhOhzNCWpz4ScOZHhtxcG+QZu6/1fXpAYObtP+0fDXu6oVvoP4gzAuOjf4y461t yY5MlxlHoFj3atyFWdHIRK6xxjYpHlrSPndCPP/RjaqYa58ie0+sO4pUQEXKjRo6+jhm 53LyC3FZIUL0fmfzRiM9A9cel8CIyo/49cxBtneihZq6BeIu026XXuLv/Dz00Es9Qy2k bXPA== X-Gm-Message-State: ACrzQf1ifOiAG4iWli9vOYnyC7dHeencZlbC4mT5sbQlCnmoPum+CFgT Qa+azk+NdONDQ6IEIVesTmCyRJ0h8Rj9sgjgIxikAIngbpP9pM55moPcKrKzCcdfG88+/jyzGLi oIKHtdcTqA/F+ewg1wGIOkpzy8yU6SpvDhqD43Tb0CGWnDQYdEKZQSGDu/3I39ps6V5s= X-Received: by 2002:a05:6214:226b:b0:4ad:70ba:d04f with SMTP id gs11-20020a056214226b00b004ad70bad04fmr3011488qvb.56.1663777031297; Wed, 21 Sep 2022 09:17:11 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4qwydrlzQb17J7D25hscykFWGORwtGC8jyW68XaUjQ7pGMIB0spnCl1vz8iL0UsY5wBbD1eA== X-Received: by 2002:a05:6214:226b:b0:4ad:70ba:d04f with SMTP id gs11-20020a056214226b00b004ad70bad04fmr3011457qvb.56.1663777030938; Wed, 21 Sep 2022 09:17:10 -0700 (PDT) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id m19-20020a05620a24d300b006be8713f742sm2274009qkn.38.2022.09.21.09.17.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Sep 2022 09:17:09 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++ modules: partial variable template specializations [PR106826] Date: Wed, 21 Sep 2022 12:16:29 -0400 Message-Id: <20220921161629.1738016-1-ppalka@redhat.com> X-Mailer: git-send-email 2.38.0.rc0.52.gdda7228a83 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.4 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_LOW, 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: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Cc: nathan@acm.org Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" With partial variable template specializations, it looks like we stream the VAR_DECL (i.e. the DECL_TEMPLATE_RESULT of the corresponding TEMPLATE_DECL) since process_partial_specialization adds it to the specializations table, but end up never streaming the corresponding TEMPLATE_DECL itself that appears only in the primary template's DECL_TEMPLATE_SPECIALIZATIONS list, which leads to the list being incomplete on stream-in. The modules machinery already has special logic for streaming partial specializations of class templates; this patch generalizes it to handle those of variable templates as well. Tested on x86_64-pc-linux-gnu, does this look OK for trunk? PR c++/106826 gcc/cp/ChangeLog: * module.cc (trees_out::decl_value): Use get_template_info in the MK_partial case. (trees_out::key_mergeable): Likewise. (trees_in::key_mergeable): Likewise. (has_definition): Consider DECL_INITIAL of a partial variable template specialization. (depset::hash::make_dependency): Introduce a dependency of partial variable template specializations too. gcc/testsuite/ChangeLog: * g++.dg/modules/partial-2_a.C: New test. * g++.dg/modules/partial-2_b.C: New test. --- gcc/cp/module.cc | 32 +++++++++------- gcc/testsuite/g++.dg/modules/partial-2_a.C | 43 ++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/partial-2_b.C | 21 +++++++++++ 3 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/partial-2_a.C create mode 100644 gcc/testsuite/g++.dg/modules/partial-2_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 9a9ef4e3332..334bde99b0f 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -7789,8 +7789,9 @@ trees_out::decl_value (tree decl, depset *dep) } else { - tree_node (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner))); - tree_node (CLASSTYPE_TI_ARGS (TREE_TYPE (inner))); + tree ti = get_template_info (inner); + tree_node (TI_TEMPLATE (ti)); + tree_node (TI_ARGS (ti)); } } tree_node (get_constraints (decl)); @@ -10626,8 +10627,9 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, case MK_partial: { key.constraints = get_constraints (inner); - key.ret = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (inner)); - key.args = CLASSTYPE_TI_ARGS (TREE_TYPE (inner)); + tree ti = get_template_info (inner); + key.ret = TI_TEMPLATE (ti); + key.args = TI_ARGS (ti); } break; } @@ -10866,8 +10868,8 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, spec; spec = TREE_CHAIN (spec)) { tree tmpl = TREE_VALUE (spec); - if (template_args_equal (key.args, - CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))) + tree ti = get_template_info (tmpl); + if (template_args_equal (key.args, TI_ARGS (ti)) && cp_tree_equal (key.constraints, get_constraints (DECL_TEMPLATE_RESULT (tmpl)))) @@ -11381,8 +11383,7 @@ has_definition (tree decl) case VAR_DECL: if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_INFO (decl) - && DECL_USE_TEMPLATE (decl) < 2) + && DECL_TEMPLATE_INFO (decl)) return DECL_INITIAL (decl); else { @@ -12498,11 +12499,14 @@ depset::hash::make_dependency (tree decl, entity_kind ek) if (!dep) { - if (DECL_IMPLICIT_TYPEDEF_P (decl) - /* ... not an enum, for instance. */ - && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) - && TYPE_LANG_SPECIFIC (TREE_TYPE (decl)) - && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2) + if ((DECL_IMPLICIT_TYPEDEF_P (decl) + /* ... not an enum, for instance. */ + && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) + && TYPE_LANG_SPECIFIC (TREE_TYPE (decl)) + && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)) == 2) + || (VAR_P (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_USE_TEMPLATE (decl) == 2)) { /* A partial or explicit specialization. Partial specializations might not be in the hash table, because @@ -12515,7 +12519,7 @@ depset::hash::make_dependency (tree decl, entity_kind ek) dep_hash, and then convert the dep we just found into a redirect. */ - tree ti = TYPE_TEMPLATE_INFO (TREE_TYPE (decl)); + tree ti = get_template_info (decl); tree tmpl = TI_TEMPLATE (ti); tree partial = NULL_TREE; for (tree spec = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); diff --git a/gcc/testsuite/g++.dg/modules/partial-2_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C new file mode 100644 index 00000000000..2681bb59ce8 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C @@ -0,0 +1,43 @@ +// PR c++/106826 +// { dg-additional-options -fmodules-ts } +// { dg-module-cmi pr106826 } +export module pr106826; + +template constexpr bool is_reference_v = false; +template constexpr bool is_reference_v = true; +template constexpr bool is_reference_v = true; + +struct A { + template static constexpr bool is_reference_v = false; +}; + +template constexpr bool A::is_reference_v = true; +template constexpr bool A::is_reference_v = true; + +#if __cpp_concepts +namespace concepts { + template bool is_reference_v; + + template requires __is_same(T, T&) + constexpr bool is_reference_v = true; + + template requires __is_same(T, T&&) && (!__is_same(T, T&)) + constexpr bool is_reference_v = true; + + template requires (!__is_same(T, T&)) && (!__is_same(T, T&&)) + constexpr bool is_reference_v = false; + + struct A { + template static bool is_reference_v; + }; + + template requires __is_same(T, T&) + constexpr bool A::is_reference_v = true; + + template requires __is_same(T, T&&) && (!__is_same(T, T&)) + constexpr bool A::is_reference_v = true; + + template requires (!__is_same(T, T&)) && (!__is_same(T, T&&)) + constexpr bool A::is_reference_v = false; +} +#endif diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C new file mode 100644 index 00000000000..0af41ef5e5e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C @@ -0,0 +1,21 @@ +// PR c++/106826 +// { dg-additional-options -fmodules-ts } +module pr106826; + +static_assert(is_reference_v); +static_assert(is_reference_v); +static_assert(!is_reference_v); + +static_assert(A::is_reference_v); +static_assert(A::is_reference_v); +static_assert(!A::is_reference_v); + +#if __cpp_concepts +static_assert(concepts::is_reference_v); +static_assert(concepts::is_reference_v); +static_assert(!concepts::is_reference_v); + +static_assert(concepts::A::is_reference_v); +static_assert(concepts::A::is_reference_v); +static_assert(!concepts::A::is_reference_v); +#endif