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.133.124]) by sourceware.org (Postfix) with ESMTPS id BADB13858D35 for ; Thu, 7 Mar 2024 20:58:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BADB13858D35 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 BADB13858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709845099; cv=none; b=dzhJC/bfGauXb4ZFiukGSF07q1mYo+CYR4gOj7434YJf5g632NeX6b4XxzSQ9u1qgRENk0lvobYrrNmmYKSYcS3N8xJCZMPOri6d34xpnFI8pJP5cVnjQoeeyET3DPp3iXnaELkajZrkwPL7M48kLytG1gOtyf1SO08bHHVQlrc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1709845099; c=relaxed/simple; bh=/ZLRKLi/uhcxdP6VShtjJoYmvT2k0CTeVS1qLA1tBZE=; h=DKIM-Signature:From:Date:To:Subject:Message-ID:MIME-Version; b=UqEmzMfeLeOSMkf38bkS+AHnm0LATEp3Wg41vBxTh3BngWASa3nIm3yhDsE0Wsoe5v27eV82JErv2mZuFrrggtPSt04cNnsIL9UYr6cezNx1oOQ75NPQK8bq/PxmZbVSaTctkDZJhCwWYA1Z8JxAkJ8EIW4stxoLz9t8gV+iG94= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1709845095; 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=PqSoQ3+WM5O6p338na1T8m8qgUFmO54De1pITET/hl8=; b=jBA8sk46+nwF8QyRSDOefocdJVIJapg1sXWPibNsHMiIBKIvCyMkzHdfCRherOXcOlR1fU sn1yQpCYT8QjRQcLZT4a20FQ2ImBypCEhg+bILNrq1eZClJa6l2DcSfKP9cbvlB/XJa75w 80TGxAcMXWg8okNjr5U8ZNB4GpNhqEk= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-442-Hvjg7i94OLa4n9nnJRH2Yg-1; Thu, 07 Mar 2024 15:58:13 -0500 X-MC-Unique: Hvjg7i94OLa4n9nnJRH2Yg-1 Received: by mail-qk1-f199.google.com with SMTP id af79cd13be357-787d2fab065so120965085a.3 for ; Thu, 07 Mar 2024 12:58:13 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709845092; x=1710449892; 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=PqSoQ3+WM5O6p338na1T8m8qgUFmO54De1pITET/hl8=; b=Bbenj7cKIAArVzZShvWRAGY71jVWG7d/ptRzPlsJ1gWN/+Nc1CV4eQdEIyEDoEmkux 9skS/0uLAvvdc1xx79TrXoMzzlG0YNhMCiUOWRI2OL/5LT56HrhvpyY1nEqrfxlh1uLg 1VpaysfwoKJ1j3oEr30s5EhbcMPQNIt9ssfpDvvlGHbX2D5xdAUkneVBf+0FU6tc2Ikd cvlHk8+LPscV7uscE6nA7YPkkc35VM8ZIDbuNFi4jDdRHTj/gs/5ezd7poXAOrih8GCQ oJ9dXuGZgxHEnr407/AmIoz7zEfJk4Er4/X++vPLxS0uPajLB3yDoruuvMh4aei3f2ya +oEg== X-Forwarded-Encrypted: i=1; AJvYcCX5tYJ4ebkDgnnUiv+sq+xnvfBp8LSIYuAScS/vM1hsIdK5n3fDZ6CuYDNFfvjmThdW1lEqk7/mW0BXHxXLI1EGP94eqL+apQ== X-Gm-Message-State: AOJu0YwtU7EHL4qjUnTQB2o196x+3BJj6jxA86GcgqPuf9qFvQokO1VO tbwY2zaVP/qqbI3udHLPN8APQRqKw7Golg1EC4O+oepg1s4tuSD/5OtjqBzO+Wq4GDaMuFu2hhY oViIwtUhIokPrKYhzQKZsS2rCPsks3giuf5t0GTd57UURka3KLyKGW7fhM4v2FzA= X-Received: by 2002:a05:620a:3bcd:b0:788:22e4:aec5 with SMTP id yf13-20020a05620a3bcd00b0078822e4aec5mr9698116qkn.57.1709845092139; Thu, 07 Mar 2024 12:58:12 -0800 (PST) X-Google-Smtp-Source: AGHT+IFiBvk+YSGFH7xN/xpp+edhn7gjyHW9gmbTQNTGdIaaaIsj90AF/09Kna2Rn5LYB5c9WrMAKg== X-Received: by 2002:a05:620a:3bcd:b0:788:22e4:aec5 with SMTP id yf13-20020a05620a3bcd00b0078822e4aec5mr9698098qkn.57.1709845091649; Thu, 07 Mar 2024 12:58:11 -0800 (PST) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id f2-20020a05620a12e200b007883c06d6c7sm2499400qkl.82.2024.03.07.12.58.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Mar 2024 12:58:11 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Thu, 7 Mar 2024 15:58:10 -0500 (EST) To: Jason Merrill cc: Patrick Palka , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] c++/modules: member alias tmpl partial inst [PR103994] In-Reply-To: <3bdbe404-a1a1-41de-a567-09b1d82a8e68@redhat.com> Message-ID: References: <20240304222654.1511204-1-ppalka@redhat.com> <61fbdfa3-e7ad-48bc-ba06-42ae41cfcf4f@redhat.com> <3d1cf4f7-7931-902d-c28d-e4e2af887593@idea> <9add3ac2-6a43-1c87-7a38-3194368a37aa@idea> <3bdbe404-a1a1-41de-a567-09b1d82a8e68@redhat.com> 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=-12.5 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,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,RCVD_IN_SORBS_WEB,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, Jason Merrill wrote: > On 3/7/24 14:41, Patrick Palka wrote: > > 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. > > OK. Thanks a lot. > > > -- >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); > > + } > > I'm surprised we don't still need the call to coerce_template_parms, a bit > below this? Luckily we can skip it since instantiate_alias_template already immediately calls coerce_template_parms. I guess that's a nice benefit of calling instantiate_alias_template directly instead of going through tsubst. > > > /* 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 > int>>::rebind_alloc'} module } } > > +// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key > > \(specialization\) type_decl:'::allocator_traits<::allocator > int>>::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(); > > +} > >