From: Jason Merrill Date: Mon, 11 May 2020 19:46:59 +0000 (-0400) Subject: c++: tree walk into TYPENAME_TYPE. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f50f6daa140186a048cbf33f54f4591eabf5f12;p=gcc.git 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 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. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f2814c3b037..5195a0a043f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2020-05-11 Jason Merrill + + 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 * call.c (implicit_conversion_error): Split out from... 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 void m(j f) { template void o() { auto p = [](auto i) { if constexpr (a{}) ; + if constexpr (typename a::t{}); // { dg-error "" } }; m(p); }