From: Patrick Palka <ppalka@redhat.com>
To: Patrick Palka <ppalka@redhat.com>
Cc: Jason Merrill <jason@redhat.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++/modules: member alias tmpl partial inst [PR103994]
Date: Thu, 7 Mar 2024 14:41:25 -0500 (EST) [thread overview]
Message-ID: <9add3ac2-6a43-1c87-7a38-3194368a37aa@idea> (raw)
In-Reply-To: <3d1cf4f7-7931-902d-c28d-e4e2af887593@idea>
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<B>::key_arg<T> 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<B>) 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) <case depset::EK_SPECIALIZATION>:
> 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) <case TEMPLATE_DECL>: Adjust after
removing is_alias_tmpl_inst.
(trees_in::decl_value): Adjust add_mergeable_specialization
calls.
(trees_out::get_merge_kind) <case depset::EK_SPECIALIZATION>:
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<DB_UNREACHED_BIT> ();
}
- bool is_alias_tmpl_inst () const
- {
- return get_flag_bit<DB_ALIAS_TMPL_INST_BIT> ();
- }
- bool is_alias () const
- {
- return get_flag_bit<DB_ALIAS_SPEC_BIT> ();
- }
bool is_hidden () const
{
return get_flag_bit<DB_HIDDEN_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<DB_ALIAS_TMPL_INST_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 <spec_entry *> (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<DB_ALIAS_SPEC_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<spec_entry> ();
*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<long int>>::template rebind_alloc<_Up>'} module } }
// { dg-final { scan-lang-dump {Writing decl tmpl spec:-[0-9]* type_decl:'::allocator_traits<::allocator<long int>>::template rebind_alloc<_Up>'} module } }
-// { dg-final { scan-lang-dump {Writing:-[0-9]*'s alias spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<long int>'} module } }
+// { dg-final { scan-lang-dump {Writing:-[0-9]*'s decl spec merge key \(specialization\) type_decl:'::allocator_traits<::allocator<long int>>::rebind_alloc<long int>'} 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<class>
+struct A {
+ template<class> using key_arg = int;
+};
+
+struct B {
+ template<class T>
+ void f() {
+ using type = A<B>::key_arg<T>;
+ }
+};
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<int>();
+}
--
2.44.0.117.g43072b4ca1
next prev parent reply other threads:[~2024-03-07 19:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-04 22:26 Patrick Palka
2024-03-07 3:55 ` Jason Merrill
2024-03-07 16:06 ` Patrick Palka
2024-03-07 19:41 ` Patrick Palka [this message]
2024-03-07 20:43 ` Jason Merrill
2024-03-07 20:58 ` Patrick Palka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9add3ac2-6a43-1c87-7a38-3194368a37aa@idea \
--to=ppalka@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).