From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1663777034; 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=yIWwX4AQhFHqzPXtZ68+cj/vMpJgHVoP+cpqKuUjrys=; b=GU7jKPxwM0Vy/q+YlLsrWKrk1/gQliHP8Oj9Czr/kFbQQl4N1y8QRNcHwHObt+WhzDWVZa XCcSmsKTW7q3SeLTH1LgMhblSS2oytzCSqbm59nck2/hB18yqYOYcjUn/MSN6xzCGf/2u1 syKk+96s7Esx3oerGUynTnTlwogBg3o= 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) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, nathan@acm.org, Patrick Palka 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 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true 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 List-Id: 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 -- 2.38.0.rc0.52.gdda7228a83