On Wed, 2 Jun 2021, Jason Merrill wrote:

> On 6/2/21 2:39 PM, Patrick Palka wrote:
> > Here, the dependent template name in the return type of f() resolves to
> > an alias of int& after substitution, and we end up complaining about
> > qualifying this reference type with 'const' from cp_build_qualified_type
> > rather than just silently dropping the qualification as per [dcl.ref]/1.
> 
> Hmm, the patch looks fine, but why does the TYPE_DECL test fail for the alias?

Ah, I hadn't considered investigating that.  It seems make_typename_type
always returns a _TYPE instead of a TYPE_DECL when resolving a dependent
name that's a template-id, regardless of the tf_keep_type_decl flag.
This can be easily fixed like so, and this change alone is sufficient to
fix the PR (no changes to qualttp20.C needed).  Note that this change
should only have an effect when tf_keep_type_decl is passed to
make_typename_type, and the only such caller is the TYPENAME_TYPE case
of tsubst in question, so this change seems pretty safe.

The downside is that we don't get the __restrict__-dropping
"improvement" as exhibited by qualttp20.C that the original patch
provides, so this other approach is more conservative in that sense.

So shall we go with the original patch, or something like the following?
(If we go with the original patch, it just occurred to me that we could
remove tf_keep_type_decl altogether.)  Testing in progress.

-- >8 --

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb21a3a1ae8..1be232af483 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4136,10 +4136,15 @@ make_typename_type (tree context, tree name, enum 
tag_types tag_type,
     return error_mark_node;

   if (want_template)
-    return lookup_template_class (t, TREE_OPERAND (fullname, 1),
-                                 NULL_TREE, context,
-                                 /*entering_scope=*/0,
-                                 complain | tf_user);
+    {
+      t = lookup_template_class (t, TREE_OPERAND (fullname, 1),
+                                NULL_TREE, context,
+                                /*entering_scope=*/0,
+                                complain | tf_user);
+      if (!TYPE_P (t))
+       return t;
+      t = TYPE_NAME (t);
+    }

   if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
     t = TREE_TYPE (t);

Reply via email to