Commit f18aa3a4 by Jason Merrill Committed by Jason Merrill

PR c++/86740, ICE with constexpr if and nested generic lambdas.

When we partially instantiate the constexpr if, we walk through its body to
see what it uses from the enclosing local_specializations.  That walk was
overlooking the use of 'count' in the captures of the innermost lambda,
because we weren't walking into the capture list.

	* tree.c (cp_walk_subtrees): Handle LAMBDA_EXPR.

From-SVN: r268046
parent ba29ed0f
2019-01-17 Jason Merrill <jason@redhat.com>
PR c++/86740, ICE with constexpr if and nested generic lambdas.
* tree.c (cp_walk_subtrees): Handle LAMBDA_EXPR.
2019-01-17 Paolo Carlini <paolo.carlini@oracle.com> 2019-01-17 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (grokdeclarator): Use typespec_loc in error messages * decl.c (grokdeclarator): Use typespec_loc in error messages
......
...@@ -4933,6 +4933,14 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func, ...@@ -4933,6 +4933,14 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
} }
break; break;
case LAMBDA_EXPR:
/* Don't walk into the body of the lambda, but the capture initializers
are part of the enclosing context. */
for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
cap = TREE_CHAIN (cap))
WALK_SUBTREE (TREE_VALUE (cap));
break;
default: default:
return NULL_TREE; return NULL_TREE;
} }
......
// PR c++/86740
// { dg-do compile { target c++17 } }
struct Constant
{
static constexpr int value = 0;
};
template<typename F>
void invokeWithConstant(F &&f)
{
f(Constant{});
}
int foo()
{
int count = 0;
invokeWithConstant
([&] (auto id1)
{
invokeWithConstant
([&] (auto id2)
{
if constexpr (id1.value == 0 && id2.value == 0)
[&] { count = 1; } ();
});
});
return count;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment