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 9ED1A3858D35 for ; Thu, 7 Mar 2024 19:41:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9ED1A3858D35 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 9ED1A3858D35 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=1709840494; cv=none; b=Ap1HdY2ZGGop6e8CNwpJ0xhlr59X7Mub33KMjjmixpy0QCA+614rqF1jYu3/hVwrzlCOQRrEi39gf6+dMruhSWjZQV2ysm5caHerUPu84v+AiNeklCqMX4W5mXclKKck7EwyLqrAUhIIkQcDS1efBl2JsdVsfM997Obh4nnvW+I= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709840494; c=relaxed/simple; bh=Uvq/UkEIh8okNSXorhNkf3hfNllDrkURZc0JaKOHwUg=; h=DKIM-Signature:From:Date:To:Subject:Message-ID:MIME-Version; b=DV+xybXMGuBBvHj/DbMlusnleqGKr8FsBw2J8KzbSuUHFhw1NFj+oBFKkpopHolxfaipHb3Ldvoh6zXTXfHDjTaTUc4gIll9ZntP3q01t+UTgNLW5mvU+lSVrY7uzMQ4JVoL16ws+K9ONykYQi+Fu4KdHwxVU1rJAnVPvuopin4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709840490; 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: in-reply-to:in-reply-to:references:references; bh=iCrOslywo+VeyzkXw4jq0+oBq8AIx98pB5KHfOg1VYs=; b=QdqTQu7UFJ+SWbY5bjurg5/yrzy75dUeO7tVehUFlXo0J1F/jPZ5t0QXi6by2GM7qLSzMZ rWWN3FlOLKv0Hd2k9+GlJSDY4LgxHH4w14eW3HKE9Z/D/sxFGbILsYYZbZUp90e04qi7br RAY4u/lB4WIubkyb/rxO/v2YwdyO9q4= Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-635-dwo9aMszOF6N3k5lEgGnHQ-1; Thu, 07 Mar 2024 14:41:28 -0500 X-MC-Unique: dwo9aMszOF6N3k5lEgGnHQ-1 Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-787c43db5e0so113384885a.2 for ; Thu, 07 Mar 2024 11:41:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709840488; x=1710445288; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iCrOslywo+VeyzkXw4jq0+oBq8AIx98pB5KHfOg1VYs=; b=XXOXvRlncmykpOtoMEbYE2Xwa/l+TcPE90Y4VAh1K1RbRFsGuHkw8CdwSP0kw6uwM8 gD9V8YrG2PhY/RjRopSjrqvghIzGGzQHLS7PUt0/EeiV9hKK06dP6KeIOVNcAU+sPSFh 2izdF+aR2/tmRfqjPnKv5VJviXdhGBkZmxWoueLQr5e8Fw95TsxfCoJce+74Ol96q9Ws nn9mxvpht5nUpSqPKT9RE469OmxZc6eula6y7epk/4tLGSUOIXxScpkl7qgDezD1x1Jr HXhArqkJtOFEW1lsxne2V2q4xY8qlNvjxzw/Era1aXHoSLKrJiUNpW+Vi4qqhp+XIQuH +jcQ== X-Forwarded-Encrypted: i=1; AJvYcCV39qhJE5EGdX+QUrkLYLaJ+amZWfCod6QKsE8raXmo9mPEBPrduXYdmnYcmVg4fAf8gaR23u9OZ0OTPLH9QBYSDLnqDDGeQg== X-Gm-Message-State: AOJu0YwImU+gkqaXwbwBQJnzaS1D9ot56Ah3/DbWSDgr6opqBUTTm6nv qeJDp79+K28mdMnQ83peYm/gbpbqOAfC/DWOBP/teGCj+81uC7zIJhicMZoYV19l+04LaH4SPnI QXEd55xsN5q2YnU/umsW2pjM8uqikbSvTIIAzN3IMf2dDtU5D6eR7oYo= X-Received: by 2002:a05:620a:309:b0:788:264a:73c2 with SMTP id s9-20020a05620a030900b00788264a73c2mr10006417qkm.39.1709840487718; Thu, 07 Mar 2024 11:41:27 -0800 (PST) X-Google-Smtp-Source: AGHT+IF9Z99npWnY1/PSpOLJCqp2fg87k5UpS6RAsnInHKmiSKU5JQDo4/rbsYtcC4K+8S13sd13Rg== X-Received: by 2002:a05:620a:309:b0:788:264a:73c2 with SMTP id s9-20020a05620a030900b00788264a73c2mr10006392qkm.39.1709840487148; Thu, 07 Mar 2024 11:41:27 -0800 (PST) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id l5-20020ae9f005000000b00787ce45ed49sm8025827qkg.67.2024.03.07.11.41.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Mar 2024 11:41:26 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Thu, 7 Mar 2024 14:41:25 -0500 (EST) To: Patrick Palka cc: Jason Merrill , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] c++/modules: member alias tmpl partial inst [PR103994] In-Reply-To: <3d1cf4f7-7931-902d-c28d-e4e2af887593@idea> Message-ID: <9add3ac2-6a43-1c87-7a38-3194368a37aa@idea> References: <20240304222654.1511204-1-ppalka@redhat.com> <61fbdfa3-e7ad-48bc-ba06-42ae41cfcf4f@redhat.com> <3d1cf4f7-7931-902d-c28d-e4e2af887593@idea> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-13.2 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,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE,URIBL_BLACK 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: On Thu, 7 Mar 2024, Patrick Palka wrote: > On Wed, 6 Mar 2024, Jason Merrill wrote: > > > On 3/4/24 17:26, Patrick Palka wrote: > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > > > OK for trunk? > > > > > > -- >8 -- > > > > > > Alias templates are weird in that their specializations can appear in > > > both decl_specializations and type_specializations. They appear in the > > > latter only at parse time via finish_template_type. This should probably > > > be revisited in GCC 15 since it seems sufficient to store them only in > > > decl_specializations. > > > > It looks like most all of lookup_template_class is wrong for alias templates. > > > > Can we move the alias template handling up higher and unconditionally return > > the result of tsubst? > > This works nicely (although we have to use instantiate_alias_template > directly instead of tsubst since tsubst would first substitute the > uncoerced arguments into the generic DECL_TI_ARGS which breaks for > for parameter packs). And it allows for some nice simplifications in > the modules code which had to handle alias template specializations > specially. > > Bootstrapped and regtested on x86_64-pc-linux-gnu. > > -- >8 -- > > Subject: [PATCH] c++/modules: member alias tmpl partial inst [PR103994] > > Alias templates are weird in that their specializations can appear in > both decl_specializations and type_specializations. They appear in the > type table only at parse time via finish_template_type. There seems > to be no good reason for this, and the code paths end up stepping over > each other in particular for a partial alias template instantiation such > as A::key_arg in the below modules testcase: the type code path > (lookup_template_class) wants to set TI_TEMPLATE to the most general > template whereas the decl code path (tsubst_template_decl called during > instantiation of A) already set TI_TEMPLATE to the partially > instantiated TEMPLATE_DECL. This ends up confusing modules which > decides to stream the logically equivalent TYPE_DECL and TEMPLATE_DECL > for this partial alias template instantiation separately. > > This patch fixes this by making lookup_template_class dispatch to > instantiatie_alias_template early for alias template specializations. > In turn we now only add such specializations to the decl table and > not also the type table. This admits some nice simplification in > the modules code which otherwise has to cope with such specializations > appearing in both tables. > > PR c++/103994 > > gcc/cp/ChangeLog: > > * cp-tree.h (add_mergeable_specialization): Remove is_alias > parameter. > * module.cc (depset::disc_bits::DB_ALIAS_SPEC_BIT): Remove. > (depset::is_alias): Remove. > (merge_kind::MK_tmpl_alias_mask): Remove. > (merge_kind::MK_alias_spec): Remove. > (merge_kind_name): Remove entries for alias specializations. > (trees_in::decl_value): Adjust add_mergeable_specialization > calls. > (trees_out::get_merge_kind) : > Use MK_decl_spec for alias template specializations. > (trees_out::key_mergeable): Simplify after MK_tmpl_alias_mask > removal. > (specialization_add): Don't allow alias templates when !decl_p. > (depset::hash::add_specializations): Remove now-dead code > accomodating alias template specializations in the type table. > * pt.cc (lookup_template_class): Dispatch early to > instantiate_alias_template for alias templates. Simplify > accordingly. > (add_mergeable_specialization): Remove alias_p parameter and > simplify accordingly. > > gcc/testsuite/ChangeLog: > > * g++.dg/modules/pr99425-1_b.H: s/alias/decl in dump scan. > * g++.dg/modules/tpl-alias-1_a.H: Likewise. > * g++.dg/modules/tpl-alias-2_a.H: New test. > * g++.dg/modules/tpl-alias-2_b.C: New test. > --- > gcc/cp/cp-tree.h | 3 +- > gcc/cp/module.cc | 50 ++---------- > gcc/cp/pt.cc | 84 ++++++++------------ > gcc/testsuite/g++.dg/modules/pr99425-1_b.H | 2 +- > gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H | 2 +- > gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H | 15 ++++ > gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C | 9 +++ > 7 files changed, 69 insertions(+), 96 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H > create mode 100644 gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 4469d965ef0..14895bc6585 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -7642,8 +7642,7 @@ extern void walk_specializations (bool, > void *); > extern tree match_mergeable_specialization (bool is_decl, spec_entry *); > extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec); > -extern void add_mergeable_specialization (bool is_decl, bool is_alias, > - spec_entry *, > +extern void add_mergeable_specialization (bool is_decl, spec_entry *, > tree outer, unsigned); > extern tree add_to_template_args (tree, tree); > extern tree add_outermost_template_args (tree, tree); > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index 4ecd6d7c813..cc038ee9cba 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -2306,10 +2306,7 @@ private: > /* The following bits are not independent, but enumerating them is > awkward. */ > DB_ALIAS_TMPL_INST_BIT, /* An alias template instantiation. */ It seems we don't need DB_ALIAS_TMPL_INST_BIT anymore either, so the updated patch below removes it too. -- >8 -- PR c++/103994 gcc/cp/ChangeLog: * cp-tree.h (add_mergeable_specialization): Remove is_alias parameter. * module.cc (depset::disc_bits::DB_ALIAS_TMPL_INST_BIT): Remove. (depset::disc_bits::DB_ALIAS_SPEC_BIT): Remove. (depset::is_alias_tmpl_inst): Remove. (depset::is_alias): Remove. (merge_kind::MK_tmpl_alias_mask): Remove. (merge_kind::MK_alias_spec): Remove. (merge_kind_name): Remove entries for alias specializations. (trees_out::core_vals) : Adjust after removing is_alias_tmpl_inst. (trees_in::decl_value): Adjust add_mergeable_specialization calls. (trees_out::get_merge_kind) : Use MK_decl_spec for alias template specializations. (trees_out::key_mergeable): Simplify after MK_tmpl_alias_mask removal. (depset::hash::make_dependency): Adjust after removing DB_ALIAS_TMPL_INST_BIT. (specialization_add): Don't allow alias templates when !decl_p. (depset::hash::add_specializations): Remove now-dead code accomodating alias template specializations in the type table. * pt.cc (lookup_template_class): Dispatch early to instantiate_alias_template for alias templates. Simplify accordingly. (add_mergeable_specialization): Remove alias_p parameter and simplify accordingly. gcc/testsuite/ChangeLog: * g++.dg/modules/pr99425-1_b.H: s/alias/decl in dump scan. * g++.dg/modules/tpl-alias-1_a.H: Likewise. * g++.dg/modules/tpl-alias-2_a.H: New test. * g++.dg/modules/tpl-alias-2_b.C: New test. --- gcc/cp/cp-tree.h | 3 +- gcc/cp/module.cc | 86 ++++---------------- gcc/cp/pt.cc | 84 ++++++++----------- gcc/testsuite/g++.dg/modules/pr99425-1_b.H | 2 +- gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H | 2 +- gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H | 15 ++++ gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C | 9 ++ 7 files changed, 78 insertions(+), 123 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H create mode 100644 gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4469d965ef0..14895bc6585 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7642,8 +7642,7 @@ extern void walk_specializations (bool, void *); extern tree match_mergeable_specialization (bool is_decl, spec_entry *); extern unsigned get_mergeable_specialization_flags (tree tmpl, tree spec); -extern void add_mergeable_specialization (bool is_decl, bool is_alias, - spec_entry *, +extern void add_mergeable_specialization (bool is_decl, spec_entry *, tree outer, unsigned); extern tree add_to_template_args (tree, tree); extern tree add_outermost_template_args (tree, tree); diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 4ecd6d7c813..dfe4536c0ae 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -2305,11 +2305,7 @@ private: DB_HIDDEN_BIT, /* A hidden binding. */ /* The following bits are not independent, but enumerating them is awkward. */ - DB_ALIAS_TMPL_INST_BIT, /* An alias template instantiation. */ - DB_ALIAS_SPEC_BIT, /* Specialization of an alias template - (in both spec tables). */ - DB_TYPE_SPEC_BIT, /* Specialization in the type table. - */ + DB_TYPE_SPEC_BIT, /* Specialization in the type table. */ DB_FRIEND_SPEC_BIT, /* An instantiated template friend. */ }; @@ -2400,14 +2396,6 @@ public: { return get_flag_bit (); } - bool is_alias_tmpl_inst () const - { - return get_flag_bit (); - } - bool is_alias () const - { - return get_flag_bit (); - } bool is_hidden () const { return get_flag_bit (); @@ -2782,13 +2770,11 @@ enum merge_kind MK_template_mask = 0x10, /* A template specialization. */ MK_tmpl_decl_mask = 0x4, /* In decl table. */ - MK_tmpl_alias_mask = 0x2, /* Also in type table */ MK_tmpl_tmpl_mask = 0x1, /* We want TEMPLATE_DECL. */ MK_type_spec = MK_template_mask, MK_decl_spec = MK_template_mask | MK_tmpl_decl_mask, - MK_alias_spec = MK_decl_spec | MK_tmpl_alias_mask, MK_hwm = 0x20 }; @@ -2806,7 +2792,7 @@ static char const *const merge_kind_name[MK_hwm] = NULL, NULL, "decl spec", "decl tmpl spec", /* 20,21 decl (template). */ - "alias spec", "alias tmpl spec", /* 22,23 alias (template). */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; @@ -6356,8 +6342,7 @@ trees_out::core_vals (tree t) gcc_checking_assert (TREE_VISITED (((lang_tree_node *)t)->template_decl.arguments)); gcc_checking_assert - (TREE_VISITED (((lang_tree_node *)t)->template_decl.result) - || dep_hash->find_dependency (t)->is_alias_tmpl_inst ()); + (TREE_VISITED (((lang_tree_node *)t)->template_decl.result)); if (DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (t)) WT (DECL_CHAIN (t)); break; @@ -8306,16 +8291,13 @@ trees_in::decl_value () { bool is_type = TREE_CODE (inner) == TYPE_DECL; spec.spec = is_type ? type : inner; - add_mergeable_specialization (!is_type, false, - &spec, decl, spec_flags); + add_mergeable_specialization (!is_type, &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, - &spec, decl, spec_flags); + add_mergeable_specialization (!is_type, &spec, decl, spec_flags); } if (NAMESPACE_SCOPE_P (decl) @@ -8392,7 +8374,7 @@ trees_in::decl_value () if (!e) { spec.spec = inner; - add_mergeable_specialization (true, false, &spec, decl, spec_flags); + add_mergeable_specialization (true, &spec, decl, spec_flags); } else if (e != existing) set_overrun (); @@ -10620,8 +10602,6 @@ trees_out::get_merge_kind (tree decl, depset *dep) mk = MK_friend_spec; else if (dep->is_type_spec ()) mk = MK_type_spec; - else if (dep->is_alias ()) - mk = MK_alias_spec; else mk = MK_decl_spec; @@ -10732,11 +10712,6 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner, gcc_assert (existing); if (mk & MK_tmpl_decl_mask) { - if (mk & MK_tmpl_alias_mask) - /* It should be in both tables. */ - gcc_checking_assert - (same_type_p (match_mergeable_specialization (false, entry), - TREE_TYPE (existing))); if (mk & MK_tmpl_tmpl_mask) existing = DECL_TI_TEMPLATE (existing); } @@ -12830,17 +12805,12 @@ depset::hash::make_dependency (tree decl, entity_kind ek) bindings. */ *slot = dep = make_entity (decl, ek, has_def); - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (DECL_ALIAS_TEMPLATE_P (decl) && DECL_TEMPLATE_INFO (decl)) - dep->set_flag_bit (); - else if (CHECKING_P) - /* The template_result should otherwise not be in the - table, or be an empty redirect (created above). */ - if (auto *eslot = entity_slot (DECL_TEMPLATE_RESULT (decl), false)) - gcc_checking_assert ((*eslot)->get_entity_kind () == EK_REDIRECT - && !(*eslot)->deps.length ()); - } + if (CHECKING_P && TREE_CODE (decl) == TEMPLATE_DECL) + /* The template_result should otherwise not be in the + table, or be an empty redirect (created above). */ + if (auto *eslot = entity_slot (DECL_TEMPLATE_RESULT (decl), false)) + gcc_checking_assert ((*eslot)->get_entity_kind () == EK_REDIRECT + && !(*eslot)->deps.length ()); if (ek != EK_USING) { @@ -13228,16 +13198,11 @@ specialization_add (bool decl_p, spec_entry *entry, void *data_) heuristic. We don't attempt to replicate that algorithm, but observe its behaviour and reproduce it upon read back. */ - gcc_checking_assert (DECL_ALIAS_TEMPLATE_P (entry->tmpl) - || TREE_CODE (entry->spec) == ENUMERAL_TYPE + gcc_checking_assert (TREE_CODE (entry->spec) == ENUMERAL_TYPE || DECL_CLASS_TEMPLATE_P (entry->tmpl)); - /* Only alias templates can appear in both tables (and - if they're in the type table they must also be in the decl - table). */ gcc_checking_assert - (!match_mergeable_specialization (true, entry) - == !DECL_ALIAS_TEMPLATE_P (entry->tmpl)); + (!match_mergeable_specialization (true, entry)); } else if (VAR_OR_FUNCTION_DECL_P (entry->spec)) gcc_checking_assert (!DECL_LOCAL_DECL_P (entry->spec)); @@ -13293,7 +13258,6 @@ depset::hash::add_specializations (bool decl_p) spec_entry *entry = data.pop (); tree spec = entry->spec; int use_tpl = 0; - bool is_alias = false; bool is_friend = false; if (decl_p && DECL_UNINSTANTIATED_TEMPLATE_FRIEND_P (entry->tmpl)) @@ -13301,13 +13265,7 @@ depset::hash::add_specializations (bool decl_p) instantiation. */ is_friend = true; - if (!decl_p && DECL_ALIAS_TEMPLATE_P (entry->tmpl)) - { - spec = TYPE_NAME (spec); - is_alias = true; - } - - if (decl_p || is_alias) + if (decl_p) { if (tree ti = DECL_TEMPLATE_INFO (spec)) { @@ -13392,20 +13350,10 @@ depset::hash::add_specializations (bool decl_p) gcc_checking_assert (!TREE_VISITED (spec)); depset *dep = make_dependency (spec, depset::EK_SPECIALIZATION); if (dep->is_special ()) - { - /* An already located specialization, this must be the TYPE - corresponding to an alias_decl we found in the decl - table. */ - spec_entry *other = reinterpret_cast (dep->deps[0]); - gcc_checking_assert (!decl_p && is_alias && !dep->is_type_spec ()); - gcc_checking_assert (other->tmpl == entry->tmpl - && template_args_equal (other->args, entry->args) - && TREE_TYPE (other->spec) == entry->spec); - dep->set_flag_bit (); - } + gcc_unreachable (); else { - gcc_checking_assert (decl_p || !is_alias); + gcc_checking_assert (decl_p); if (dep->get_entity_kind () == depset::EK_REDIRECT) dep = dep->deps[0]; else if (dep->get_entity_kind () == depset::EK_SPECIALIZATION) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d73f6d93485..99aa64b1cc3 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -10055,6 +10055,32 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, /* Now we should have enough arguments. */ gcc_assert (parm_depth == arg_depth); + if (DECL_ALIAS_TEMPLATE_P (gen_tmpl)) + { + /* The user referred to a specialization of an alias + template represented by GEN_TMPL. + + [temp.alias]/2 says: + + When a template-id refers to the specialization of an + alias template, it is equivalent to the associated + type obtained by substitution of its + template-arguments for the template-parameters in the + type-id of the alias template. */ + + t = instantiate_alias_template (gen_tmpl, arglist, complain); + /* Note that the call above (by indirectly calling + register_specialization in tsubst_decl) registers the + TYPE_DECL representing the specialization of the alias + template. So next time someone substitutes ARGLIST for + the template parms into the alias template (GEN_TMPL), + she'll get that TYPE_DECL back. */ + + if (t == error_mark_node) + return error_mark_node; + return TREE_TYPE (t); + } + /* From here on, we're only interested in the most general template. */ @@ -10120,7 +10146,6 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, lookup. This prevents redundant checks on previously instantiated specializations. */ if (flag_concepts - && !DECL_ALIAS_TEMPLATE_P (gen_tmpl) && !constraints_satisfied_p (gen_tmpl, arglist)) { if (complain & tf_error) @@ -10189,31 +10214,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, context = global_namespace; /* Create the type. */ - if (DECL_ALIAS_TEMPLATE_P (gen_tmpl)) - { - /* The user referred to a specialization of an alias - template represented by GEN_TMPL. - - [temp.alias]/2 says: - - When a template-id refers to the specialization of an - alias template, it is equivalent to the associated - type obtained by substitution of its - template-arguments for the template-parameters in the - type-id of the alias template. */ - - t = tsubst (TREE_TYPE (gen_tmpl), arglist, complain, in_decl); - /* Note that the call above (by indirectly calling - register_specialization in tsubst_decl) registers the - TYPE_DECL representing the specialization of the alias - template. So next time someone substitutes ARGLIST for - the template parms into the alias template (GEN_TMPL), - she'll get that TYPE_DECL back. */ - - if (t == error_mark_node) - return t; - } - else if (TREE_CODE (template_type) == ENUMERAL_TYPE) + if (TREE_CODE (template_type) == ENUMERAL_TYPE) { if (!is_dependent_type) { @@ -10301,8 +10302,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, } } - if (OVERLOAD_TYPE_P (t) - && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)) + if (OVERLOAD_TYPE_P (t)) { static const char *tags[] = {"abi_tag", "may_alias"}; @@ -10369,7 +10369,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, { TREE_VEC_LENGTH (arglist)--; ++processing_template_decl; - tree tinfo = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (TREE_TYPE (gen_tmpl)); + tree tinfo = TYPE_TEMPLATE_INFO (TREE_TYPE (gen_tmpl)); tree partial_inst_args = tsubst (INNERMOST_TEMPLATE_ARGS (TI_ARGS (tinfo)), arglist, complain, NULL_TREE); @@ -10407,17 +10407,9 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, TEMPLATE_PARM_LEVEL. */ found = tsubst (gen_tmpl, arglist, tf_none, NULL_TREE); TREE_VEC_LENGTH (arglist)++; - /* FOUND is either a proper class type, or an alias - template specialization. In the later case, it's a - TYPE_DECL, resulting from the substituting of arguments - for parameters in the TYPE_DECL of the alias template - done earlier. So be careful while getting the template - of FOUND. */ found = (TREE_CODE (found) == TEMPLATE_DECL ? found - : (TREE_CODE (found) == TYPE_DECL - ? DECL_TI_TEMPLATE (found) - : CLASSTYPE_TI_TEMPLATE (found))); + : CLASSTYPE_TI_TEMPLATE (found)); if (DECL_CLASS_TEMPLATE_P (found) && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (found))) @@ -10447,8 +10439,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, DECL_TEMPLATE_INSTANTIATIONS (found)); if (TREE_CODE (template_type) == ENUMERAL_TYPE - && !uses_template_parms (current_nonlambda_scope ()) - && !DECL_ALIAS_TEMPLATE_P (gen_tmpl)) + && !uses_template_parms (current_nonlambda_scope ())) /* Now that the type has been registered on the instantiations list, we set up the enumerators. Because the enumeration constants may involve the enumeration type itself, we make @@ -31578,8 +31569,8 @@ get_mergeable_specialization_flags (tree tmpl, tree decl) get_mergeable_specialization_flags. */ void -add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt, - tree decl, unsigned flags) +add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl, + unsigned flags) { hashval_t hash = spec_hasher::hash (elt); if (decl_p) @@ -31590,15 +31581,8 @@ add_mergeable_specialization (bool decl_p, bool alias_p, spec_entry *elt, auto entry = ggc_alloc (); *entry = *elt; *slot = entry; - - if (alias_p) - { - elt->spec = TREE_TYPE (elt->spec); - gcc_checking_assert (elt->spec); - } } - - if (!decl_p || alias_p) + else { auto *slot = type_specializations->find_slot_with_hash (elt, hash, INSERT); diff --git a/gcc/testsuite/g++.dg/modules/pr99425-1_b.H b/gcc/testsuite/g++.dg/modules/pr99425-1_b.H index 53d28b4ef5e..e75b3129dd3 100644 --- a/gcc/testsuite/g++.dg/modules/pr99425-1_b.H +++ b/gcc/testsuite/g++.dg/modules/pr99425-1_b.H @@ -15,5 +15,5 @@ inline void widget (Cont parm) ssize (parm); } -// { dg-final { scan-lang-dump {Read:-[0-9]*'s alias spec merge key \(new\) type_decl:'::make_signed_t'\n ... Read:-[0-9]*'s type spec merge key \(new\) type_decl:'::make_signed'\n Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template ssize'} module } } +// { dg-final { scan-lang-dump {Read:-[0-9]*'s decl spec merge key \(new\) type_decl:'::make_signed_t'\n ... Read:-[0-9]*'s type spec merge key \(new\) type_decl:'::make_signed'\n Read:-[0-9]*'s named merge key \(matched\) template_decl:'::template ssize'} module } } diff --git a/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H b/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H index 37002ee9ae1..14a25be586f 100644 --- a/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H +++ b/gcc/testsuite/g++.dg/modules/tpl-alias-1_a.H @@ -6,4 +6,4 @@ // { dg-final { scan-lang-dump {Writing decl tmpl spec:-[0-9]* template_decl:'::allocator_traits<::allocator>::template rebind_alloc<_Up>'} module } } // { dg-final { scan-lang-dump {Writing decl tmpl spec:-[0-9]* type_decl:'::allocator_traits<::allocator>::template rebind_alloc<_Up>'} module } } -// { dg-final { scan-lang-dump {Writing:-[0-9]*'s alias spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator>::rebind_alloc'} module } } +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator>::rebind_alloc'} module } } diff --git a/gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H b/gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H new file mode 100644 index 00000000000..76917f778e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-alias-2_a.H @@ -0,0 +1,15 @@ +// PR c++/103994 +// { dg-additional-options -fmodule-header } +// { dg-module-cmi {} } + +template +struct A { + template using key_arg = int; +}; + +struct B { + template + void f() { + using type = A::key_arg; + } +}; diff --git a/gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C b/gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C new file mode 100644 index 00000000000..44fa5f42757 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/tpl-alias-2_b.C @@ -0,0 +1,9 @@ +// PR c++/103994 +// { dg-additional-options -fmodules-ts } + +import "tpl-alias-2_a.H"; + +int main() { + B b; + b.f(); +} -- 2.44.0.117.g43072b4ca1