diff mbox series

[pushed] c++: tree walk into TYPENAME_TYPE.

Message ID 20200511201950.22511-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: tree walk into TYPENAME_TYPE. | expand

Commit Message

Jason Merrill May 11, 2020, 8:19 p.m. UTC
While looking at 92583/92654 it occurred to me that typename types needed
the same fix.  So extract_locals_r also needs to see the TYPE_CONTEXT of a
TYPENAME_TYPE.  But it must not look through a typedef.

Most tree walking in the front end wants to walk through the syntactic form
of a type of expression, and doesn't care about the type referred to by a
typedef.  But min_vis_r does care.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog
2020-05-11  Jason Merrill  <jason@redhat.com>

	PR c++/92583
	PR c++/92654
	* tree.c (cp_walk_subtrees): Stop at typedefs.
	Handle TYPENAME_TYPE here.
	* pt.c (find_parameter_packs_r): Not here.
	(for_each_template_parm_r): Clear *walk_subtrees.
	* decl2.c (min_vis_r): Look through typedefs.
---
 gcc/cp/decl2.c                                | 30 +++++++++++--------
 gcc/cp/pt.c                                   |  7 +----
 gcc/cp/tree.c                                 | 22 +++++++++++---
 .../g++.dg/cpp1z/constexpr-if-lambda3.C       |  1 +
 4 files changed, 37 insertions(+), 23 deletions(-)


base-commit: 42e9f80bf4f6a38733c221c03a512c432cdb784f
diff mbox series

Patch

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8d3ac31a0c9..4767d53adef 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2328,26 +2328,30 @@  static tree
 min_vis_r (tree *tp, int *walk_subtrees, void *data)
 {
   int *vis_p = (int *)data;
+  int this_vis = VISIBILITY_DEFAULT;
   if (! TYPE_P (*tp))
-    {
-      *walk_subtrees = 0;
-    }
+    *walk_subtrees = 0;
+  else if (typedef_variant_p (*tp))
+    /* Look through typedefs despite cp_walk_subtrees.  */
+    this_vis = type_visibility (DECL_ORIGINAL_TYPE (TYPE_NAME (*tp)));
   else if (OVERLOAD_TYPE_P (*tp)
 	   && !TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
     {
-      *vis_p = VISIBILITY_ANON;
-      return *tp;
+      this_vis = VISIBILITY_ANON;
+      *walk_subtrees = 0;
+    }
+  else if (CLASS_TYPE_P (*tp))
+    {
+      this_vis = CLASSTYPE_VISIBILITY (*tp);
+      *walk_subtrees = 0;
     }
-  else if (CLASS_TYPE_P (*tp)
-	   && CLASSTYPE_VISIBILITY (*tp) > *vis_p)
-    *vis_p = CLASSTYPE_VISIBILITY (*tp);
   else if (TREE_CODE (*tp) == ARRAY_TYPE
 	   && uses_template_parms (TYPE_DOMAIN (*tp)))
-    {
-      int evis = expr_visibility (TYPE_MAX_VALUE (TYPE_DOMAIN (*tp)));
-      if (evis > *vis_p)
-	*vis_p = evis;
-    }
+    this_vis = expr_visibility (TYPE_MAX_VALUE (TYPE_DOMAIN (*tp)));
+
+  if (this_vis > *vis_p)
+    *vis_p = this_vis;
+
   return NULL;
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 28f3c90f17b..86f1bb7470d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3963,12 +3963,6 @@  find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
 		    &find_parameter_packs_r, ppd, ppd->visited);
       return NULL_TREE;
 
-    case TYPENAME_TYPE:
-      cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r,
-                   ppd, ppd->visited);
-      *walk_subtrees = 0;
-      return NULL_TREE;
-
     case TYPE_PACK_EXPANSION:
     case EXPR_PACK_EXPANSION:
       *walk_subtrees = 0;
@@ -10321,6 +10315,7 @@  for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       /* A template-id in a TYPENAME_TYPE might be a deduced context after
 	 partial instantiation.  */
       WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (t));
+      *walk_subtrees = 0;
       break;
 
     case CONSTRUCTOR:
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8840932dba2..d526a6311e0 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -5006,9 +5006,18 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
   while (0)
 
   if (TYPE_P (*tp))
-    /* Walk into template args without looking through typedefs.  */
-    if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (*tp))
-      WALK_SUBTREE (TI_ARGS (ti));
+    {
+      /* Walk into template args without looking through typedefs.  */
+      if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (*tp))
+	WALK_SUBTREE (TI_ARGS (ti));
+      /* Don't look through typedefs; walk_tree_fns that want to look through
+	 typedefs (like min_vis_r) need to do that themselves.  */
+      if (typedef_variant_p (*tp))
+	{
+	  *walk_subtrees_p = 0;
+	  return NULL_TREE;
+	}
+    }
 
   /* Not one of the easy cases.  We must explicitly go through the
      children.  */
@@ -5021,7 +5030,6 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
     case UNBOUND_CLASS_TEMPLATE:
     case TEMPLATE_PARM_INDEX:
     case TEMPLATE_TYPE_PARM:
-    case TYPENAME_TYPE:
     case TYPEOF_TYPE:
     case UNDERLYING_TYPE:
       /* None of these have subtrees other than those already walked
@@ -5029,6 +5037,12 @@  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       *walk_subtrees_p = 0;
       break;
 
+    case TYPENAME_TYPE:
+      WALK_SUBTREE (TYPE_CONTEXT (*tp));
+      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
+      *walk_subtrees_p = 0;
+      break;
+
     case BASELINK:
       if (BASELINK_QUALIFIED_P (*tp))
 	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
index 34615f71ee2..fa9a4b6d8c0 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C
@@ -18,6 +18,7 @@  template <auto l, typename j> void m(j f) {
 template <int, int c> void o() {
   auto p = [](auto i) {
     if constexpr (a<i>{}) ;
+    if constexpr (typename a<i>::t{});	// { dg-error "" }
   };
   m<c>(p);
 }