public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Patrick Palka <ppalka@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++/modules: member alias tmpl partial inst [PR103994]
Date: Thu, 7 Mar 2024 15:43:05 -0500	[thread overview]
Message-ID: <3bdbe404-a1a1-41de-a567-09b1d82a8e68@redhat.com> (raw)
In-Reply-To: <9add3ac2-6a43-1c87-7a38-3194368a37aa@idea>

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.

> -- >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?

>         /* 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	other threads:[~2024-03-07 20:43 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
2024-03-07 20:43       ` Jason Merrill [this message]
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=3bdbe404-a1a1-41de-a567-09b1d82a8e68@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=ppalka@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).