public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] c++: Fix push_access_scope and introduce RAII wrapper for it
@ 2021-06-29 17:57 Patrick Palka
  2021-06-29 17:57 ` [PATCH 2/2] c++: Extend PR96204 fix to variable templates Patrick Palka
  2021-06-29 18:45 ` [PATCH 1/2] c++: Fix push_access_scope and introduce RAII wrapper for it Jason Merrill
  0 siblings, 2 replies; 9+ messages in thread
From: Patrick Palka @ 2021-06-29 17:57 UTC (permalink / raw)
  To: gcc-patches

When push_access_scope is passed a TYPE_DECL for a class type (which
can happen during e.g. satisfaction), we undesirably push only the
enclosing context of the class instead of the class itself.  This causes
us to mishandle e.g. testcase below due to us not entering the scope of
A before checking its constraints.

This patch adjusts push_access_scope accordingly, and introduces an
RAII wrapper for it.  We also make use of this wrapper right away by
replacing the only use of push_nested_class_guard with this new wrapper,
which means we can remove this old wrapper (whose functionality is
basically subsumed by the new wrapper).

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

gcc/cp/ChangeLog:

	* constraint.cc (get_normalized_constraints_from_decl): Use
	push_access_scope_guard instead of push_nested_class_guard.
	* cp-tree.h (struct push_nested_class_guard): Replace with ...
	(struct push_access_scope_guard): ... this.
	* pt.c (push_access_scope): When the argument corresponds to
	a class type, push the class instead of its context.
	(pop_access_scope): Adjust accordingly.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-access2.C: New test.
---
 gcc/cp/constraint.cc                          |  7 +-----
 gcc/cp/cp-tree.h                              | 23 +++++++++++--------
 gcc/cp/pt.c                                   |  9 +++++++-
 gcc/testsuite/g++.dg/cpp2a/concepts-access2.C | 13 +++++++++++
 4 files changed, 35 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-access2.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 6df3ca6ce32..99d3ccc6998 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -926,12 +926,7 @@ get_normalized_constraints_from_decl (tree d, bool diag = false)
   tree norm = NULL_TREE;
   if (tree ci = get_constraints (decl))
     {
-      push_nested_class_guard pncs (DECL_CONTEXT (d));
-
-      temp_override<tree> ovr (current_function_decl);
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-	current_function_decl = decl;
-
+      push_access_scope_guard pas (decl);
       norm = get_normalized_constraints_from_info (ci, tmpl, diag);
     }
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6f713719589..58da7460001 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8463,21 +8463,24 @@ is_constrained_auto (const_tree t)
   return is_auto (t) && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
 }
 
-/* RAII class to push/pop class scope T; if T is not a class, do nothing.  */
+/* RAII class to push/pop the access scope for T.  */
 
-struct push_nested_class_guard
+struct push_access_scope_guard
 {
-  bool push;
-  push_nested_class_guard (tree t)
-    : push (t && CLASS_TYPE_P (t))
+  tree decl;
+  push_access_scope_guard (tree t)
+    : decl (t)
   {
-    if (push)
-      push_nested_class (t);
+    if (VAR_OR_FUNCTION_DECL_P (decl)
+	|| TREE_CODE (decl) == TYPE_DECL)
+      push_access_scope (decl);
+    else
+      decl = NULL_TREE;
   }
-  ~push_nested_class_guard ()
+  ~push_access_scope_guard ()
   {
-    if (push)
-      pop_nested_class ();
+    if (decl)
+      pop_access_scope (decl);
   }
 };
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f2039e09cd7..bd8b17ca047 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -224,7 +224,7 @@ static void instantiate_body (tree pattern, tree args, tree d, bool nested);
 /* Make the current scope suitable for access checking when we are
    processing T.  T can be FUNCTION_DECL for instantiated function
    template, VAR_DECL for static member variable, or TYPE_DECL for
-   alias template (needed by instantiate_decl).  */
+   for a class or alias template (needed by instantiate_decl).  */
 
 void
 push_access_scope (tree t)
@@ -234,6 +234,10 @@ push_access_scope (tree t)
 
   if (DECL_FRIEND_CONTEXT (t))
     push_nested_class (DECL_FRIEND_CONTEXT (t));
+  else if (TREE_CODE (t) == TYPE_DECL
+	   && CLASS_TYPE_P (TREE_TYPE (t))
+	   && DECL_ORIGINAL_TYPE (t) == NULL_TREE)
+    push_nested_class (TREE_TYPE (t));
   else if (DECL_CLASS_SCOPE_P (t))
     push_nested_class (DECL_CONTEXT (t));
   else if (deduction_guide_p (t) && DECL_ARTIFICIAL (t))
@@ -260,6 +264,9 @@ pop_access_scope (tree t)
     current_function_decl = saved_access_scope->pop();
 
   if (DECL_FRIEND_CONTEXT (t)
+      || (TREE_CODE (t) == TYPE_DECL
+	  && CLASS_TYPE_P (TREE_TYPE (t))
+	  && DECL_ORIGINAL_TYPE (t) == NULL_TREE)
       || DECL_CLASS_SCOPE_P (t)
       || (deduction_guide_p (t) && DECL_ARTIFICIAL (t)))
     pop_nested_class ();
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C
new file mode 100644
index 00000000000..8ddcad236e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-access2.C
@@ -0,0 +1,13 @@
+// { dg-do compile { target concepts } }
+
+template<class T> requires T::value struct A { };
+template<class T> requires T::value struct B { }; // { dg-error "private" }
+
+struct S {
+private:
+  static constexpr bool value = true;
+  template<class T> requires T::value friend struct A;
+};
+
+A<S> x;
+B<S> y; // { dg-error "constraint" }
-- 
2.32.0.93.g670b81a890


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-06-30 20:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

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).