From patchwork Thu Oct 24 07:18:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 99473 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 78DD33858039 for ; Thu, 24 Oct 2024 07:18:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by sourceware.org (Postfix) with ESMTPS id 9C4C33858D39 for ; Thu, 24 Oct 2024 07:18:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9C4C33858D39 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9C4C33858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1032 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729754307; cv=none; b=FJe8EYr9pgiJxU5T7ZFya/rOQE3ScIaVHCGckxlOWnOcxhMO/d/o5rsIqNa2gJXMqa661c47Il3USr9REWOxVvxuWLSzmfrcih+5VGxea5ZJPBK6rS8fxtoXIq95QlaYwsscX18mo922tZgRySemdxG5J8SrczfiRqiTx7Gpl08= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729754307; c=relaxed/simple; bh=NjZ/dRPBKs3vjQ/dWhTF+mK1NTB/Xx0TJ9BXGN9VzQk=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=pXKc4kRsZXNJCXyMYa7+XYvwK8h2DYBnHV/hLKAZOuyCkgF7gU7qJ6QiSVpTnRvHILUtIBQ7LhkLk9U0x5Z16BpoaNtoGcM9GZr1ZjiiA7f6BzXAaUbd44f4mwpC8Off4CqMwECfgf/1fogbtX05438JHTRac+yvy0VXQjxsIAo= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-2e2da8529e1so94535a91.1 for ; Thu, 24 Oct 2024 00:18:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729754301; x=1730359101; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=cjH9B0O0+kYXZXB1AyM+/5hdy9vZyYsn6YDtpN8EZgM=; b=l4wJDlJ/CzVAyrwfoNkBdVa3onvw6zGS6taMMMSei96IzzPWsJx9d/Q+Ior7/stmTB JCsPHV2Rk/7FnDh2Z2ihWcrx8Qiv32UQCP7PRE5NDG+On6KgDbRwlYqZCeLGTAQ4DHdJ O1/EXvr22H2yjBEeXmbgsPdZIxYRtazv0bJPcbdkKzVoVqVaZyAFMhEMlOaNBxNZTvIa YcFYCex2VFGctRxYA+EriRinv7YA1Pc301nwdtgL+CxTNp9i7Vb7dlU0/Mm0Q+b7WGwW zNLWyseTUDQq9/nNEEbCdIHwdmDIbeqgs4pcGfTbkb15+GaFD3tZ/PYuFCXRAnJsQ2xc fvxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729754301; x=1730359101; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=cjH9B0O0+kYXZXB1AyM+/5hdy9vZyYsn6YDtpN8EZgM=; b=R9yXox7IRtyZFVVLaOA1WRYYq1CucE3su0EuwyST0izN8Xw8DauC7SqKCwk/bSCACD 4MobhXo+jFSHGyT8wu9wXqn2QAOeNfqFo+EMd8h32fWdZQzNRZ/q/nj36tGf7FW9wrMu hk7OLREfZTEbvh7RqjyqmcrZVV+cdRpBYn15wrUyDBPS88Pf8uCXWTRc147jIo7AdANg e+CUlYTZIBw7x3strlpztL27a1/MrpEnBLDSlTihVwRbtIxymErkJKmDTfBFLZw6uaeU qpzrGfuoRyUityFQNHv76hS05c2UuKbuHuEwZ3usP61Pn4fstvdGO4Ic0244YDG47uIL Tc+A== X-Gm-Message-State: AOJu0YwMNiUcvLbbIJLX1LITN3znG+eBIGHNZg4LwxhrWCfpESmbQH6u zaLGWEr4HgCTExpAWd+w2j0XJErXl2tW7CKsffnDJfO+RfEPltnVNEhKN2mA X-Google-Smtp-Source: AGHT+IGb6I+z3FlAJvJ6tKWVyicbIaiU1od5Y8C2k/WM+3M1TgHvHTQCMXQQY0Dgcc6HKXXv3FbECw== X-Received: by 2002:a17:90b:3cd:b0:2e2:a60f:289e with SMTP id 98e67ed59e1d1-2e76b204452mr2605062a91.0.1729754301250; Thu, 24 Oct 2024 00:18:21 -0700 (PDT) Received: from Thaum. ([163.47.68.2]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2e77e558114sm715918a91.36.2024.10.24.00.18.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Oct 2024 00:18:20 -0700 (PDT) Message-ID: <6719f4bc.170a0220.367ad4.1d4a@mx.google.com> X-Google-Original-Message-ID: Date: Thu, 24 Oct 2024 18:18:16 +1100 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell Subject: [PATCH 1/2] c++/modules: Propagate some missing flags on type definitions MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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~patchwork=sourceware.org@gcc.gnu.org Bootstrapped and regtested on x86_64-pc-linux-gnu. I did a quick skim to see if I could find any more likely missing flags but I think this should be all of them now. -- >8 -- Noticed while testing my fix for PR c++/113814. Not all of these are easily testable but I've tested a couple that were straight-forward. For consistency also adds a new TYPE_WARN_IF_NOT_ALIGN_RAW flag to match the decl version Nathan added. gcc/cp/ChangeLog: * module.cc (trees_in::read_class_def): Propagate some missing flags from the streamed-in definition. gcc/ChangeLog: * tree.h (TYPE_WARN_IF_NOT_ALIGN_RAW): New accessor. (TYPE_WARN_IF_NOT_ALIGN): Use it. (SET_TYPE_WARN_IF_NOT_ALIGN): Likewise. gcc/testsuite/ChangeLog: * g++.dg/modules/class-10_a.H: New test. * g++.dg/modules/class-10_b.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/module.cc | 20 +++++++++++++++++++- gcc/testsuite/g++.dg/modules/class-10_a.H | 6 ++++++ gcc/testsuite/g++.dg/modules/class-10_b.C | 19 +++++++++++++++++++ gcc/tree.h | 8 +++++--- 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/class-10_a.H create mode 100644 gcc/testsuite/g++.dg/modules/class-10_b.C diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index fd9b1d3bf2e..e8c9a876903 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -12379,8 +12379,12 @@ trees_in::read_class_def (tree defn, tree maybe_template) /* Core pieces. */ TYPE_MODE_RAW (type) = TYPE_MODE_RAW (type_dup); + TYPE_ALIGN_RAW (type) = TYPE_ALIGN_RAW (type_dup); + TYPE_WARN_IF_NOT_ALIGN_RAW (type) + = TYPE_WARN_IF_NOT_ALIGN_RAW (type_dup); + TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (type_dup); + SET_DECL_MODE (defn, DECL_MODE (maybe_dup)); - TREE_ADDRESSABLE (type) = TREE_ADDRESSABLE (type_dup); DECL_SIZE (defn) = DECL_SIZE (maybe_dup); DECL_SIZE_UNIT (defn) = DECL_SIZE_UNIT (maybe_dup); DECL_ALIGN_RAW (defn) = DECL_ALIGN_RAW (maybe_dup); @@ -12388,12 +12392,26 @@ trees_in::read_class_def (tree defn, tree maybe_template) = DECL_WARN_IF_NOT_ALIGN_RAW (maybe_dup); DECL_USER_ALIGN (defn) = DECL_USER_ALIGN (maybe_dup); + TYPE_TYPELESS_STORAGE (type) = TYPE_TYPELESS_STORAGE (type_dup); + TYPE_CXX_ODR_P (type) = TYPE_CXX_ODR_P (type_dup); + TYPE_NO_FORCE_BLK (type) = TYPE_NO_FORCE_BLK (type_dup); + TYPE_TRANSPARENT_AGGR (type) = TYPE_TRANSPARENT_AGGR (type_dup); + TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type) + = TYPE_CONTAINS_PLACEHOLDER_INTERNAL (type_dup); + + TYPE_EMPTY_P (type) = TYPE_EMPTY_P (type_dup); + TREE_ADDRESSABLE (type) = TREE_ADDRESSABLE (type_dup); + /* C++ pieces. */ TYPE_POLYMORPHIC_P (type) = TYPE_POLYMORPHIC_P (type_dup); + CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (type_dup); + TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (type_dup); TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type_dup); + TYPE_NEEDS_CONSTRUCTING (type) + = TYPE_NEEDS_CONSTRUCTING (type_dup); if (auto ls = TYPE_LANG_SPECIFIC (type_dup)) { diff --git a/gcc/testsuite/g++.dg/modules/class-10_a.H b/gcc/testsuite/g++.dg/modules/class-10_a.H new file mode 100644 index 00000000000..177cf57fec1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/class-10_a.H @@ -0,0 +1,6 @@ +// { dg-additional-options "-fmodule-header" } +// { dg-module-cmi {} } + +struct alignas(16) Align {}; +struct Final final {}; +struct NeedsConstructing { NeedsConstructing(); }; diff --git a/gcc/testsuite/g++.dg/modules/class-10_b.C b/gcc/testsuite/g++.dg/modules/class-10_b.C new file mode 100644 index 00000000000..2f982124f3e --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/class-10_b.C @@ -0,0 +1,19 @@ +// { dg-additional-options "-fmodules-ts -Wno-pedantic" } +// Test bits and pieces of merging information +// from class defs into forward declarations + +struct Align; +struct Final; +struct NeedsConstructing; + +import "class-10_a.H"; + +static_assert(alignof(Align) == 16); + +struct TestFinal : Final {}; // { dg-error "cannot derive" } + +struct TestNeedsConstructing { + struct { + NeedsConstructing a; // { dg-error "with constructor not allowed in anonymous aggregate" } + }; +}; diff --git a/gcc/tree.h b/gcc/tree.h index f4c89f5477c..1bd43531b9c 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2357,13 +2357,15 @@ extern tree vector_element_bits_tree (const_tree); /* The minimum alignment necessary for objects of this type without warning. The value is an int, measured in bits. */ +#define TYPE_WARN_IF_NOT_ALIGN_RAW(NODE) \ + (TYPE_CHECK (NODE)->type_common.warn_if_not_align) #define TYPE_WARN_IF_NOT_ALIGN(NODE) \ - (TYPE_CHECK (NODE)->type_common.warn_if_not_align \ - ? ((unsigned)1) << ((NODE)->type_common.warn_if_not_align - 1) : 0) + (TYPE_WARN_IF_NOT_ALIGN_RAW (NODE) \ + ? ((unsigned)1) << (TYPE_WARN_IF_NOT_ALIGN_RAW (NODE) - 1) : 0) /* Specify that TYPE_WARN_IF_NOT_ALIGN(NODE) is X. */ #define SET_TYPE_WARN_IF_NOT_ALIGN(NODE, X) \ - (TYPE_CHECK (NODE)->type_common.warn_if_not_align = ffs_hwi (X)) + (TYPE_WARN_IF_NOT_ALIGN_RAW (NODE) = ffs_hwi (X)) /* If your language allows you to declare types, and you want debug info for them, then you need to generate corresponding TYPE_DECL nodes. From patchwork Thu Oct 24 07:25:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathaniel Shead X-Patchwork-Id: 99475 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DA83C3858C2B for ; Thu, 24 Oct 2024 07:26:10 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id 1448D3858D21 for ; Thu, 24 Oct 2024 07:25:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1448D3858D21 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1448D3858D21 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::634 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729754731; cv=none; b=O2jQp4V9gulwDgyQtzOCdRj61KZ9D4d2RVNNCJFNkMDTYA9zgqWoEwBPnH0/Wzygb8Yz8jl2vCGXBKUsBP5Y5Pk5LM9Qq8rROHrtM4aMmov3AF7ysDKgLuZBePQSh2jpWrZ6mdvVj2hC917Aa8CfxnqJ/qi0AtncKgfC4bVpM7s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729754731; c=relaxed/simple; bh=/sRnGPX8jwkyu0f2WPYkR+Ts6cHrUclJVJQYyo+0gtc=; h=DKIM-Signature:Message-ID:Date:From:To:Subject:MIME-Version; b=olnrkz2iOki5jn1MMHX6rmo+Fc26RG9Vi2misNEVgo0Wx2lfyTrE2Zff+O22Cn9/NXvM5rW89Hq3zE9lwfjQE38HvCXKdtnSBQYgXdQJqNmE1eN7HnesKW9DBTwH8n531qzlhRslKU3aGFbyfP0nWWDM8YY56lVLiV3vECKxgpE= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-20cafd36ed0so380805ad.3 for ; Thu, 24 Oct 2024 00:25:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729754727; x=1730359527; darn=gcc.gnu.org; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=mUS9/vXWthSU3AIcKo7IVtJaVmBrUuIWF57A8CnYbaE=; b=Hnvg83S6MUq5HFJ6f9YM+D1onavGMgF893Z/x5c+l0u6QboKn3iM2j1o7Npl54PSb6 jOhevZTBcEXYfhiUoLLtzSIVxlRez3pMTtczjvk1n+o77NE3Oh86e7+RbKKNnIa652Os Kb4fmCH59a4qY76wKpyZUo2/fO5uPDgMxLERhq9kV9rzTbigj0S94vVycZYM8xJuKeZf 21zliFnpsFm956tbytnmjs4yJOh8GmeCqyKB7qe6JBwzrJmXSsQt1tECbMLNlgJ0H7A1 XuXyq8LAByvv2DujCCtzAG7gy4zY3vbB6Mk5ERzju6lhWJ3dzB2jJao7tjPvdJUI3pRO dGyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729754727; x=1730359527; h=content-disposition:mime-version:subject:cc:to:from:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=mUS9/vXWthSU3AIcKo7IVtJaVmBrUuIWF57A8CnYbaE=; b=fyIbhH/CbEzrx24YKEUtk0ayeS7rYkzV3QmiRLnxmkDR3mzznky0oJdnClHxOEC9hX MLWzofEVfEQkDpiOAx6cSWQKaGSXTPGe4HxeF7vl122Vm10DeDY3qYzac3dQLRymk/hR bLSjtZybd8YY+tRN6Uu5vR3OauScR5YOo6/ljccq0yQuC+Qf4EPiNg2spmwI2eTVfiVQ lRzRc922hk/JHi2Xk4z9kK43GYEAgWqJfl8+lHKAgQM79I4B5vpLRGpvfa+m5lSf1YlF oUKM5yJqdBoiK8DZFwyYehLLrj6JdHhBfnx7G358q7bGs/bmlp1HuIQ4ATMsCjiaClVQ GPvA== X-Gm-Message-State: AOJu0YzsBu6r58cB9NpYmtufB6OVkkchXd9LZK4GV95xqGtbWr1LyPSv c+sWQg1rYfSHT6JLTNKC1hwNq0r/15HraU4VHNvGuvH1jxj2Aaayx2S1B1gx X-Google-Smtp-Source: AGHT+IGyolFNKAsyml+mDyczCoBV2iCRv+r1Jfrj5Fm9AF6OFgsuo8RJr6OvOxgRTcdYnYDKdxGiuQ== X-Received: by 2002:a17:903:41c9:b0:20b:9b07:777a with SMTP id d9443c01a7336-20fa9e9f8efmr32161145ad.10.1729754726839; Thu, 24 Oct 2024 00:25:26 -0700 (PDT) Received: from Thaum. ([163.47.68.2]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20e7ef0e1cesm67670735ad.88.2024.10.24.00.25.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Oct 2024 00:25:26 -0700 (PDT) Message-ID: <6719f666.170a0220.29055d.ac56@mx.google.com> X-Google-Original-Message-ID: Date: Thu, 24 Oct 2024 18:25:22 +1100 From: Nathaniel Shead To: gcc-patches@gcc.gnu.org Cc: Jason Merrill , Nathan Sidwell , Patrick Palka Subject: [PATCH 2/2] c++/modules: Retrofit imported partial specs over existing implicit instantiations [PR113814] MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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~patchwork=sourceware.org@gcc.gnu.org I wasn't sure whether I should include the ambiguity checking logic from process_partial_specialization; we don't do this anywhere else in the modules handling code that I could see so I left it out for now. I could also rework process_partial_specialization to call the new create_mergeable_partial_spec function if you prefer, to reduce code duplication, though the early exit for VAR_DECL and the call to associate_classtype_constraints that relies on global state complicated it enough I didn't bother for this patch. Finally, I'm not entirely sure whether the choice of DECL_TEMPLATE_PARMS that I'm providing is correct, especially considering this hunk: /* Give template template parms a DECL_CONTEXT of the template for which they are a parameter. */ for (i = 0; i < ntparms; ++i) { tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i)); if (TREE_CODE (parm) == TEMPLATE_DECL) DECL_CONTEXT (parm) = tmpl; } I haven't been able to produce any testcase that relies on this context setting to cause a failure, though, and there doesn't seem to be one in the testsuite for the matching hunk in process_partial_specialization. Any hints on where this might be needed? Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk? -- >8 -- In some cases, when we go to import a partial specialisation there might already be an incomplete implicit instantiation in the specialisation table. This causes ICEs described in the linked PR as we now have two separate matching specialisations for this same arguments. This issue doesn't appear to happen for variable templates as it doesn't appear that we can create incomplete specialisations in the same way. This patch attempts to solve the issue by retrofitting the existing implicit instantiation as a partial specialisation (similarly to how maybe_process_partial_specialization operates) and then relying on the existing merging logic to fill in the definition of the type. This works because for types almost all relevant details are streamed and merged in 'read_class_def'. As an optimisation, we also mark the newly retrofitted specialisation as imported, since there isn't any useful information on the declaration that will be provided from this TU anyway, and so we don't need to write the decl into our own BMI but can instead just seed it as an import. PR c++/113814 gcc/cp/ChangeLog: * cp-tree.h (create_mergeable_partial_spec): * module.cc (trees_in::key_mergeable): * pt.cc (create_mergeable_partial_spec): gcc/testsuite/ChangeLog: * g++.dg/modules/partial-6.h: New test. * g++.dg/modules/partial-6_a.H: New test. * g++.dg/modules/partial-6_b.H: New test. * g++.dg/modules/partial-6_c.C: New test. Signed-off-by: Nathaniel Shead Signed-off-by: Nathaniel Shead --- gcc/cp/cp-tree.h | 1 + gcc/cp/module.cc | 26 +++++++++++ gcc/cp/pt.cc | 50 ++++++++++++++++++++++ gcc/testsuite/g++.dg/modules/partial-6.h | 7 +++ gcc/testsuite/g++.dg/modules/partial-6_a.H | 11 +++++ gcc/testsuite/g++.dg/modules/partial-6_b.H | 23 ++++++++++ gcc/testsuite/g++.dg/modules/partial-6_c.C | 12 ++++++ 7 files changed, 130 insertions(+) create mode 100644 gcc/testsuite/g++.dg/modules/partial-6.h create mode 100644 gcc/testsuite/g++.dg/modules/partial-6_a.H create mode 100644 gcc/testsuite/g++.dg/modules/partial-6_b.H create mode 100644 gcc/testsuite/g++.dg/modules/partial-6_c.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a44100a2bc4..eda287df84e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7590,6 +7590,7 @@ extern bool is_specialization_of_friend (tree, tree); extern bool comp_template_args (tree, tree, tree * = NULL, tree * = NULL); extern int template_args_equal (tree, tree); +extern tree create_mergeable_partial_spec (tree, tree, tree); extern tree maybe_process_partial_specialization (tree); extern tree most_specialized_instantiation (tree); extern tree most_specialized_partial_spec (tree, tsubst_flags_t, bool = false); diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index e8c9a876903..bb166ee38f3 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -11296,6 +11296,32 @@ trees_in::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, break; } } + + if (!existing && type && CLASS_TYPE_P (type)) + { + spec_entry spec; + spec.tmpl = key.ret; + spec.args = key.args; + spec.spec = type; + + tree inst = match_mergeable_specialization (false, &spec); + if (inst + && CLASSTYPE_IMPLICIT_INSTANTIATION (inst) + && !COMPLETE_TYPE_P (inst)) + { + /* There's an existing implicit instantiation of this partial + specialization. We'll retrofit it as a partial spec and + then load over it. */ + existing = create_mergeable_partial_spec + (TYPE_NAME (inst), DECL_TEMPLATE_PARMS (decl), + key.constraints); + + /* Despite matching an existing declaration, this is actually + an import; mark it as such so we don't need to write it + when exporting from this module. */ + DECL_MODULE_IMPORT_P (TYPE_NAME (inst)) = true; + } + } } else if (mk == MK_keyed && DECL_LANG_SPECIFIC (name) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 0141c53b617..4b32d85890b 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -5477,6 +5477,56 @@ process_partial_specialization (tree decl) return decl; } +/* DECL is an implicit instantiation of a template that we're + streaming a matching partial specialization for. Build and + return a new TEMPLATE_DECL for the the type and prepare it + as with process_partial_specialization. */ + +tree +create_mergeable_partial_spec (tree decl, tree parms, tree constraints) +{ + tree type = TREE_TYPE (decl); + tree tinfo = get_template_info (decl); + tree maintmpl = TI_TEMPLATE (tinfo); + tree specargs = TI_ARGS (tinfo); + + gcc_checking_assert (TREE_CODE (decl) == TYPE_DECL + && CLASSTYPE_IMPLICIT_INSTANTIATION (type) + && !COMPLETE_TYPE_P (type)); + SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); + + tree tmpl = build_template_decl (decl, parms, + DECL_MEMBER_TEMPLATE_P (maintmpl)); + SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); + DECL_TEMPLATE_INFO (tmpl) = build_template_info (maintmpl, specargs); + DECL_PRIMARY_TEMPLATE (tmpl) = maintmpl; + + /* Give template template parms a DECL_CONTEXT of the template + for which they are a parameter. */ + tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms); + int ntparms = TREE_VEC_LENGTH (inner_parms); + for (int i = 0; i < ntparms; ++i) + { + tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i)); + if (TREE_CODE (parm) == TEMPLATE_DECL) + DECL_CONTEXT (parm) = tmpl; + } + + set_constraints (decl, constraints); + + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) + = tree_cons (specargs, tmpl, + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); + TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + /* Link the DECL_TEMPLATE_RESULT back to the partial TEMPLATE_DECL. */ + gcc_checking_assert (!TI_PARTIAL_INFO (tinfo)); + TI_PARTIAL_INFO (tinfo) = build_template_info (tmpl, NULL_TREE); + + set_defining_module_for_partial_spec (decl); + + return tmpl; +} + /* PARM is a template parameter of some form; return the corresponding TEMPLATE_PARM_INDEX. */ diff --git a/gcc/testsuite/g++.dg/modules/partial-6.h b/gcc/testsuite/g++.dg/modules/partial-6.h new file mode 100644 index 00000000000..702c9a1b7ec --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/partial-6.h @@ -0,0 +1,7 @@ +// PR c++/113814 + +template struct A {}; +template A f(); + +template