On 7/19/24 10:30 AM, Patrick Palka wrote:
On Thu, 18 Jul 2024, Jason Merrill wrote:

On 7/18/24 12:45 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does thi look
OK for trunk/14?

-- >8 --

As a followup of r15-2047-g7954bb4fcb6fa8, we also need to consider
dependent attributes when recursing into a non-template alias that names
a dependent alias template specialization (and so STF_STRIP_DEPENDENT
is set), otherwise in the first testcase below we undesirably strip B
all the way to T instead of to A<T>.

We also need to move the typedef recursion case of strip_typedefs up to
get checked before the compound type recursion cases.  Otherwise for C
below (which ultimately aliases T*) we end up stripping it to T* instead
of to A<T*> because the POINTER_TYPE recursion dominates the typedef
recursion.  It also means we issue an unexpected extra error in the
third testcase below.

Ideally we would also want to consider dependent attributes on
non-template aliases, so that we accept the second testcase below, but
making that work correctly would require broader changes to e.g.
spec_hasher which currently assumes all non-template aliases are
stripped and hence it'd conflate the dependent specializations A<T>
and A<B> even if we didn't strip B.

Wouldn't that just be a matter of changing structural_comptypes to consider
dependent attributes as well as dependent specializations?

Pretty much, it seems.  ISTM we should check dependent attributes even
when !comparing_dependent_aliases since they affect type identity rather
than just SFINAE behavior.


Or better, adding attributes to dependent_alias_template_spec_p (and changing
its name)?  It seems like other callers would also benefit from that change.

I ended up adding a new predicate opaque_alias_p separate from
dependent_alias_template_spec_p since ISTM we need to call it from
there and from alias_template_specialization_p to avoid looking through
such aliases.

Sounds good, but I think let's add the word "dependent" to the name of the new function.

So opaque_alias_p checks for type identity of an alias, whereas
dependent_alias_template_spec_p more broadly checks for SFINAE identity.

Something like the following (as an incremental patch on top of the
previous one, to consider separately for backportings since it's riskier):

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 0620c8c023a..4d4a5cef92c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -6508,6 +6508,19 @@ alias_type_or_template_p (tree t)
          || DECL_ALIAS_TEMPLATE_P (t));
  }
+/* Return true if substituting into T would yield a different type than
+   substituting into its expansion.  */

Please discuss when to use this vs dependent_alias_template_spec_p (both here and there). Maybe just to say that any place that checks one probably also wants to check the other.

Other places that use d_a_t_s_p and seem to need adjusting: dependent_type_p_r, any_dependent_arguments_need_structural_equality_p, alias_ctad_tweaks.

+bool
+opaque_alias_p (const_tree t)
+{
+  return (TYPE_P (t)
+         && typedef_variant_p (t)
+         && uses_template_parms (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))

Checking this seems wrong; a vector of dependent size seems opaque even if it's a vector of int.

Jason

Reply via email to