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
This commit is contained in:
parent
ba29ed0f57
commit
f18aa3a407
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
* 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,
|
||||
}
|
||||
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:
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
27
gcc/testsuite/g++.dg/cpp1z/constexpr-if25.C
Normal file
27
gcc/testsuite/g++.dg/cpp1z/constexpr-if25.C
Normal file
@ -0,0 +1,27 @@
|
||||
// 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user