diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 11 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1y-init-captures.cpp | 10 |
2 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index cc2a11fccfb..65d23418631 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9653,7 +9653,16 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { // 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(); } diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp index d36882d8e5d..d681954707d 100644 --- a/clang/test/SemaCXX/cxx1y-init-captures.cpp +++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp @@ -196,3 +196,13 @@ namespace N3922 { 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}} +} +} |

