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<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.
> 
> 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) <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);
> > +   }
> 
> 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<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>();
> > +}
> 
> 

Reply via email to