summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-11 15:46:59 -0400
committerJason Merrill <jason@redhat.com>2020-05-11 16:18:11 -0400
commit0f50f6daa140186a048cbf33f54f4591eabf5f12 (patch)
tree8f6ef8ad0d40a14488583b05c26a12f7fe23a7ad
parent42e9f80bf4f6a38733c221c03a512c432cdb784f (diff)
c++: tree walk into TYPENAME_TYPE.
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. 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.
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/decl2.c28
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/tree.c22
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if-lambda3.C1
5 files changed, 46 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f2814c3b037..5195a0a043f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,15 @@
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.
+
+2020-05-11 Jason Merrill <jason@redhat.com>
+
* call.c (implicit_conversion_error): Split out from...
(perform_implicit_conversion_flags): ...here.
(build_converted_constant_expr_internal): Use it.
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;
+ 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)))
{
+ this_vis = VISIBILITY_ANON;
*walk_subtrees = 0;
}
- else if (OVERLOAD_TYPE_P (*tp)
- && !TREE_PUBLIC (TYPE_MAIN_DECL (*tp)))
+ else if (CLASS_TYPE_P (*tp))
{
- *vis_p = VISIBILITY_ANON;
- return *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);
}