When we have template arguments, we have a function and a pattern, the variable
in init-capture belongs to the pattern decl when checking if the lhs of
"max = current" is modifiable:
auto find = [max = init](auto current) {
max = current;
};
In function isReferenceToNonConstCapture, we handle the case where the decl
context for the variable is not part of the current context.
Instead of crashing, we emit an error message:
cannot assign to a variable captured by copy in a non-mutable lambda
rdar://
26997922
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@274392
91177308-0d34-0410-b5e6-
96231b3b80d8
// Decide whether the first capture was for a block or a lambda.
DeclContext *DC = S.CurContext, *Prev = nullptr;
- while (DC != var->getDeclContext()) {
+ // Decide whether the first capture was for a block or a lambda.
+ while (DC) {
+ // For init-capture, it is possible that the variable belongs to the
+ // template pattern of the current context.
+ if (auto *FD = dyn_cast<FunctionDecl>(DC))
+ if (var->isInitCapture() &&
+ FD->getTemplateInstantiationPattern() == var->getDeclContext())
+ break;
+ if (DC == var->getDeclContext())
+ break;
Prev = DC;
DC = DC->getParent();
}
auto a = [x{X()}] { return x.n; }; // ok
auto b = [x = {X()}] {}; // expected-error{{<initializer_list>}}
}
+
+namespace init_capture_non_mutable {
+void test(double weight) {
+ double init;
+ auto find = [max = init](auto current) {
+ max = current; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
+ };
+ find(weight); // expected-note {{in instantiation of function template specialization}}
+}
+}