aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/pt.cc10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-generic11.C13
2 files changed, 22 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ba1b302..85136df 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13052,6 +13052,8 @@ public:
tsubst_flags_t complain;
/* True iff we don't want to walk into unevaluated contexts. */
bool skip_unevaluated_operands = false;
+ /* The unevaluated contexts that we avoided walking. */
+ auto_vec<tree> skipped_trees;
el_data (tsubst_flags_t c)
: extra (NULL_TREE), complain (c) {}
@@ -13066,6 +13068,7 @@ extract_locals_r (tree *tp, int *walk_subtrees, void *data_)
if (data.skip_unevaluated_operands
&& unevaluated_p (TREE_CODE (*tp)))
{
+ data.skipped_trees.safe_push (*tp);
*walk_subtrees = 0;
return NULL_TREE;
}
@@ -13168,8 +13171,13 @@ extract_local_specs (tree pattern, tsubst_flags_t complain)
context). */
data.skip_unevaluated_operands = true;
cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited);
+ /* Now walk the unevaluated contexts we skipped the first time around. */
data.skip_unevaluated_operands = false;
- cp_walk_tree (&pattern, extract_locals_r, &data, &data.visited);
+ for (tree t : data.skipped_trees)
+ {
+ data.visited.remove (t);
+ cp_walk_tree (&t, extract_locals_r, &data, &data.visited);
+ }
return data.extra;
}
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-generic11.C b/gcc/testsuite/g++.dg/cpp2a/lambda-generic11.C
new file mode 100644
index 0000000..62affac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-generic11.C
@@ -0,0 +1,13 @@
+// PR c++/108999
+// { dg-do compile { target c++20 } }
+
+template<typename T>
+void ice(T a) {
+ auto aa = a;
+ auto lambda = []<int I>() {
+ if constexpr (sizeof(aa) + I != 42) { }
+ };
+ lambda.template operator()<17>();
+}
+
+template void ice(int);