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>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH 2/2] c++: Extend PR96204 fix to variable templates
Date: Tue, 29 Jun 2021 15:38:21 -0400	[thread overview]
Message-ID: <bec3f12c-3685-ece1-52fe-80acc88998a4@redhat.com> (raw)
In-Reply-To: <20210629175723.1009233-2-ppalka@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 4740 bytes --]

On 6/29/21 1:57 PM, Patrick Palka wrote:
> r12-1829 corrected the access scope during partial specialization
> matching of class templates, but neglected the variable template case.
> This patch moves the access scope adjustment to inside
> most_specialized_partial_spec, so that all callers can benefit.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?
> 
> 	PR c++/96204
> 
> gcc/cp/ChangeLog:
> 
> 	* pt.c (instantiate_class_template_1): Remove call to
> 	push_nested_class and pop_nested_class added by r12-1829.
> 	(most_specialized_partial_spec): Use push_access_scope_guard
> 	and deferring_access_check_sentinel.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/template/access40b.C: New test.
> ---
>   gcc/cp/pt.c                               | 12 +++++++----
>   gcc/testsuite/g++.dg/template/access40b.C | 26 +++++++++++++++++++++++
>   2 files changed, 34 insertions(+), 4 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/template/access40b.C
> 
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index bd8b17ca047..1e2e2ba5329 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -11776,11 +11776,8 @@ instantiate_class_template_1 (tree type)
>     deferring_access_check_sentinel acs (dk_no_deferred);
>   
>     /* Determine what specialization of the original template to
> -     instantiate; do this relative to the scope of the class for
> -     sake of access checking.  */
> -  push_nested_class (type);
> +     instantiate.  */
>     t = most_specialized_partial_spec (type, tf_warning_or_error);
> -  pop_nested_class ();
>     if (t == error_mark_node)
>       return error_mark_node;
>     else if (t)
> @@ -24989,26 +24986,33 @@ most_specialized_partial_spec (tree target, tsubst_flags_t complain)
>     tree outer_args = NULL_TREE;
>     tree tmpl, args;
>   
> +  tree decl;
>     if (TYPE_P (target))
>       {
>         tree tinfo = CLASSTYPE_TEMPLATE_INFO (target);
>         tmpl = TI_TEMPLATE (tinfo);
>         args = TI_ARGS (tinfo);
> +      decl = TYPE_NAME (target);
>       }
>     else if (TREE_CODE (target) == TEMPLATE_ID_EXPR)
>       {
>         tmpl = TREE_OPERAND (target, 0);
>         args = TREE_OPERAND (target, 1);
> +      decl = DECL_TEMPLATE_RESULT (tmpl);

Hmm, this won't get us the right scope; we get here for the result of 
finish_template_variable, where tmpl is the most general template and 
args are args for it.  So in the below testcase, tmpl is outer<T>::N<T2,U>:

template <typename T> struct outer {
   template <typename T2, typename U>
   static constexpr int f() { return N<T,int>; };

   template <typename T2, typename U>
   static const int N = f<T2, U>();
};

template <typename T>
template <typename U>
const int outer<T>::N<T,U> = 1;

int i = outer<int>::N<double,int>;

Oddly, I notice that we also get here for static data members of class 
templates that are not themselves templates, as in mem-partial1.C that I 
adapted the above from.  Fixed by the attached patch.

Since the type of the variable depends on the specialization, we can't 
actually get the decl before doing the resolution, but we should be able 
to push into the right enclosing class.  Perhaps we should pass the 
partially instantiated template and its args to lookup_template_variable 
instead of the most general template and its args.

>       }
>     else if (VAR_P (target))
>       {
>         tree tinfo = DECL_TEMPLATE_INFO (target);
>         tmpl = TI_TEMPLATE (tinfo);
>         args = TI_ARGS (tinfo);
> +      decl = target;
>       }
>     else
>       gcc_unreachable ();
>   
> +  push_access_scope_guard pas (decl);
> +  deferring_access_check_sentinel acs (dk_no_deferred);
> +
>     tree main_tmpl = most_general_template (tmpl);
>   
>     /* For determining which partial specialization to use, only the
> diff --git a/gcc/testsuite/g++.dg/template/access40b.C b/gcc/testsuite/g++.dg/template/access40b.C
> new file mode 100644
> index 00000000000..040e3d18096
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/template/access40b.C
> @@ -0,0 +1,26 @@
> +// PR c++/96204
> +// { dg-do compile { target c++14 } }
> +// A variant of access40.C where has_type_member is a variable template instead
> +// of a class template.
> +
> +template<class, class = void>
> +constexpr bool has_type_member = false;
> +
> +template<class T>
> +constexpr bool has_type_member<T, typename T::type> = true;
> +
> +struct Parent;
> +
> +struct Child {
> +private:
> +  friend struct Parent;
> +  typedef void type;
> +};
> +
> +struct Parent {
> +  static void f() {
> +    // The partial specialization does not match despite Child::type
> +    // being accessible from the current scope.
> +    static_assert(!has_type_member<Child>, "");
> +  }
> +};
> 


[-- Attachment #2: 0001-vartmp.patch --]
[-- Type: text/x-patch, Size: 747 bytes --]

From b7b34f555b54f97a9d2315d6c6a552e27e2faa9c Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Tue, 29 Jun 2021 15:11:25 -0400
Subject: [PATCH] vartmp
To: gcc-patches@gcc.gnu.org

---
 gcc/cp/pt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f2039e09cd7..d2936c106ba 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26003,7 +26003,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
   td = template_for_substitution (d);
   args = gen_args;
 
-  if (VAR_P (d))
+  if (variable_template_specialization_p (d))
     {
       /* Look up an explicit specialization, if any.  */
       tree tid = lookup_template_variable (gen_tmpl, gen_args);
-- 
2.27.0


  reply	other threads:[~2021-06-29 19:38 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-29 17:57 [PATCH 1/2] c++: Fix push_access_scope and introduce RAII wrapper for it Patrick Palka
2021-06-29 17:57 ` [PATCH 2/2] c++: Extend PR96204 fix to variable templates Patrick Palka
2021-06-29 19:38   ` Jason Merrill [this message]
2021-06-30 14:48     ` Patrick Palka
2021-06-30 20:17       ` Jason Merrill
2021-06-30 20:42         ` Patrick Palka
2021-06-29 18:45 ` [PATCH 1/2] c++: Fix push_access_scope and introduce RAII wrapper for it Jason Merrill
2021-06-30 15:03   ` Patrick Palka
2021-06-30 16:20     ` Jason Merrill

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=bec3f12c-3685-ece1-52fe-80acc88998a4@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).