From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1888) id 49E243858D37; Mon, 26 Sep 2022 15:30:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 49E243858D37 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664206259; bh=tOKJkQJZLFR2J6BHgeZlTb0PKmOMwiZZdCKW86BrrFU=; h=From:To:Subject:Date:From; b=X9g/UHUKliKU+11H/TnWaIsxWFJZo0aLzQvQr2v5YLh35L0KUZzQ7HD1MU5At5ccH woSZoibYe/kypom6HLlcjMM3WuzU6vHLsdonogiCi73+8CvuvCeEiKAe3W+rvk6PU9 w0Sq4OJbnAW2u8sbU0vdN0s0jaGZgGGp+xhzmPBM= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Patrick Palka To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-2878] c++ modules: variable template partial spec fixes [PR107033] X-Act-Checkin: gcc X-Git-Author: Patrick Palka X-Git-Refname: refs/heads/master X-Git-Oldrev: 1b5432b401934962affe32cd7e42e864224e8062 X-Git-Newrev: 099a66498bf7a40764002793eba66c881a251b76 Message-Id: <20220926153059.49E243858D37@sourceware.org> Date: Mon, 26 Sep 2022 15:30:59 +0000 (GMT) List-Id: https://gcc.gnu.org/g:099a66498bf7a40764002793eba66c881a251b76 commit r13-2878-g099a66498bf7a40764002793eba66c881a251b76 Author: Patrick Palka Date: Mon Sep 26 11:30:17 2022 -0400 c++ modules: variable template partial spec fixes [PR107033] In r13-2775-g32d8123cd6ce87 I missed that we need to adjust the call to add_mergeable_specialization in the MK_partial case to correctly handle variable template partial specializations (it currently assumes we're always dealing with one for a class template). This fixes an ICE when converting the testcase from that commit to use an importable header instead of a named module. PR c++/107033 gcc/cp/ChangeLog: * module.cc (trees_in::decl_value): In the MK_partial case for a variable template partial specialization, pass decl_p=true to add_mergeable_specialization, and set spec to the VAR_DECL not the TEMPLATE_DECL. * pt.cc (add_mergeable_specialization): For a variable template partial specialization, set the TREE_TYPE of the new DECL_TEMPLATE_SPECIALIZATIONS node to the TREE_TYPE of the VAR_DECL not the VAR_DECL itself. gcc/testsuite/ChangeLog: * g++.dg/modules/partial-2.cc, g++.dg/modules/partial-2.h: New files, factored out from ... * g++.dg/modules/partial-2_a.C, g++.dg/modules/partial-2_b.C: ... these. * g++.dg/modules/partial-2_c.H: New test. * g++.dg/modules/partial-2_d.C: New test. Diff: --- gcc/cp/module.cc | 17 ++++++++----- gcc/cp/pt.cc | 2 +- gcc/testsuite/g++.dg/modules/partial-2.cc | 17 +++++++++++++ gcc/testsuite/g++.dg/modules/partial-2.h | 38 +++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/partial-2_a.C | 39 +----------------------------- gcc/testsuite/g++.dg/modules/partial-2_b.C | 18 +------------- gcc/testsuite/g++.dg/modules/partial-2_c.H | 5 ++++ gcc/testsuite/g++.dg/modules/partial-2_d.C | 8 ++++++ 8 files changed, 82 insertions(+), 62 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index f23832cb56a..7496df5e843 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -8185,13 +8185,18 @@ trees_in::decl_value () /* Set the TEMPLATE_DECL's type. */ TREE_TYPE (decl) = TREE_TYPE (inner); - if (mk & MK_template_mask - || mk == MK_partial) + /* Add to specialization tables now that constraints etc are + added. */ + if (mk == MK_partial) { - /* Add to specialization tables now that constraints etc are - added. */ - bool is_type = mk == MK_partial || !(mk & MK_tmpl_decl_mask); - + bool is_type = TREE_CODE (inner) == TYPE_DECL; + spec.spec = is_type ? type : inner; + add_mergeable_specialization (!is_type, false, + &spec, decl, spec_flags); + } + else if (mk & MK_template_mask) + { + bool is_type = !(mk & MK_tmpl_decl_mask); spec.spec = is_type ? type : mk & MK_tmpl_tmpl_mask ? inner : decl; add_mergeable_specialization (!is_type, !is_type && mk & MK_tmpl_alias_mask, diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index db4e808adec..1f088fe281e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -31010,7 +31010,7 @@ add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt, /* A partial specialization. */ tree cons = tree_cons (elt->args, decl, DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl)); - TREE_TYPE (cons) = elt->spec; + TREE_TYPE (cons) = decl_p ? TREE_TYPE (elt->spec) : elt->spec; DECL_TEMPLATE_SPECIALIZATIONS (elt->tmpl) = cons; } } diff --git a/gcc/testsuite/g++.dg/modules/partial-2.cc b/gcc/testsuite/g++.dg/modules/partial-2.cc new file mode 100644 index 00000000000..1316bf5e1c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2.cc @@ -0,0 +1,17 @@ +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 diff --git a/gcc/testsuite/g++.dg/modules/partial-2.h b/gcc/testsuite/g++.dg/modules/partial-2.h new file mode 100644 index 00000000000..afcfce791b3 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2.h @@ -0,0 +1,38 @@ +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_a.C b/gcc/testsuite/g++.dg/modules/partial-2_a.C index 2681bb59ce8..1582f56f2d4 100644 --- a/gcc/testsuite/g++.dg/modules/partial-2_a.C +++ b/gcc/testsuite/g++.dg/modules/partial-2_a.C @@ -3,41 +3,4 @@ // { 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 +#include "partial-2.h" diff --git a/gcc/testsuite/g++.dg/modules/partial-2_b.C b/gcc/testsuite/g++.dg/modules/partial-2_b.C index 0af41ef5e5e..1b0c7a53e9f 100644 --- a/gcc/testsuite/g++.dg/modules/partial-2_b.C +++ b/gcc/testsuite/g++.dg/modules/partial-2_b.C @@ -2,20 +2,4 @@ // { 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 +#include "partial-2.cc" diff --git a/gcc/testsuite/g++.dg/modules/partial-2_c.H b/gcc/testsuite/g++.dg/modules/partial-2_c.H new file mode 100644 index 00000000000..bd838529ce0 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2_c.H @@ -0,0 +1,5 @@ +// PR c++/107033 +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +#include "partial-2.h" diff --git a/gcc/testsuite/g++.dg/modules/partial-2_d.C b/gcc/testsuite/g++.dg/modules/partial-2_d.C new file mode 100644 index 00000000000..ed54d3c2884 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-2_d.C @@ -0,0 +1,8 @@ +// PR c++/107033 +// { dg-additional-options -fmodules-ts } +// { dg-module-cmi pr107033 } +export module pr107033; + +import "partial-2_c.H"; + +#include "partial-2.cc"