[PATCH] c++: cv-qualified dependent name of alias tmpl [PR100592]

Jason Merrill jason@redhat.com
Wed Jun 2 21:37:42 GMT 2021


On 6/2/21 4:56 PM, Patrick Palka wrote:
> On Wed, 2 Jun 2021, Patrick Palka wrote:
> 
>> 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.
> 
> For sake of concreteness, here's the full alternative patch for
> consideration (modulo ChangeLog):

This seems better.  I think the only non-type return from 
lookup_template_class is error_mark_node; does it work to check that 
specifically rather than !TYPE_P?

> -- >8 --
> 
> ---
>   gcc/cp/decl.c                              | 13 +++++++++----
>   gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C | 13 +++++++++++++
>   2 files changed, 22 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
> 
> 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);
> diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
> new file mode 100644
> index 00000000000..6a61f93a0b0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
> @@ -0,0 +1,13 @@
> +// PR c++/100592
> +// { dg-do compile { target c++11 } }
> +
> +template<bool>
> +struct meta {
> +  template<class> using if_c = int&;
> +};
> +
> +template<bool B>
> +typename meta<B>::template if_c<void> const f();
> +
> +using type = decltype(f<true>());
> +using type = int&;
> 



More information about the Gcc-patches mailing list