[PATCH] c++: access of dtor named by qualified template-id [PR100918]

Jason Merrill jason@redhat.com
Sun Jun 6 02:34:13 GMT 2021


On 6/4/21 5:08 PM, Patrick Palka wrote:
> Here, when resolving the destructor named by Inner<int>::~Inner<int>
> (which is valid only before C++20) we end up in cp_parser_lookup_name to
> look up the name Inner relative to the scope Inner<int>.  The lookup
> naturally finds the injected-class-name Inner<int>, and because
> is_template is true, we adjust this lookup result to the TEMPLATE_DECL
> Inner, and then check access of this adjusted lookup result.  But this
> access check fails because the scope is Inner<int> and not Outer, and
> the context_for_name_lookup of the TEMPLATE_DECL is Outer.
> 
> The simplest fix seems to be to perform the access check on the original
> lookup result (the injected-class-name) instead of the TEMPLATE_DECL.
> So this patch moves the access check in cp_parser_lookup_name to before
> the injected-class-name adjustment.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

OK.

> 	PR c++/100918
> 
> gcc/cp/ChangeLog:
> 
> 	* parser.c (cp_parser_lookup_name): Check access of the lookup
> 	result before we potentially adjust an injected-class-name to
> 	its TEMPLATE_DECL.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/template/access38.C: New test.
> ---
>   gcc/cp/parser.c                          | 24 +++++++++++++-----------
>   gcc/testsuite/g++.dg/template/access38.C | 15 +++++++++++++++
>   2 files changed, 28 insertions(+), 11 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/template/access38.C
> 
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 4a46828e162..829a94b2928 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -29505,6 +29505,19 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
>     if (!decl || decl == error_mark_node)
>       return error_mark_node;
>   
> +  /* If we have resolved the name of a member declaration, check to
> +     see if the declaration is accessible.  When the name resolves to
> +     set of overloaded functions, accessibility is checked when
> +     overload resolution is done.  If we have a TREE_LIST, then the lookup
> +     is either ambiguous or it found multiple injected-class-names, the
> +     accessibility of which is trivially satisfied.
> +
> +     During an explicit instantiation, access is not checked at all,
> +     as per [temp.explicit].  */
> +  if (DECL_P (decl))
> +    check_accessibility_of_qualified_id (decl, object_type, parser->scope,
> +					 tf_warning_or_error);
> +
>     /* Pull out the template from an injected-class-name (or multiple).  */
>     if (is_template)
>       decl = maybe_get_template_decl_from_type_decl (decl);
> @@ -29531,17 +29544,6 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
>   	      || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
>   	      || BASELINK_P (decl));
>   
> -  /* If we have resolved the name of a member declaration, check to
> -     see if the declaration is accessible.  When the name resolves to
> -     set of overloaded functions, accessibility is checked when
> -     overload resolution is done.
> -
> -     During an explicit instantiation, access is not checked at all,
> -     as per [temp.explicit].  */
> -  if (DECL_P (decl))
> -    check_accessibility_of_qualified_id (decl, object_type, parser->scope,
> -					 tf_warning_or_error);
> -
>     maybe_record_typedef_use (decl);
>   
>     return cp_expr (decl, name_location);
> diff --git a/gcc/testsuite/g++.dg/template/access38.C b/gcc/testsuite/g++.dg/template/access38.C
> new file mode 100644
> index 00000000000..488f8650c97
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/template/access38.C
> @@ -0,0 +1,15 @@
> +// PR c++/100918
> +
> +struct Outer {
> +  template<class T>
> +  struct Inner { ~Inner(); };
> +};
> +
> +template<>
> +Outer::Inner<int>::~Inner<int>() { } // { dg-error "template-id" "" { target c++20 } }
> +
> +template<class T>
> +Outer::Inner<T>::~Inner<T>() { } // { dg-error "template-id" "" { target c++20 } }
> +
> +Outer::Inner<int> x;
> +Outer::Inner<char> y;
> 



More information about the Gcc-patches mailing list