Author: mren Date: Fri Jul 1 17:27:16 2016 New Revision: 274392 URL: http://llvm.org/viewvc/llvm-project?rev=274392&view=rev Log: C++14 init-capture: error out instead of crashing.
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 Modified: cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=274392&r1=274391&r2=274392&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 1 17:27:16 2016 @@ -9653,7 +9653,16 @@ static NonConstCaptureKind isReferenceTo // 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(); } Modified: cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp?rev=274392&r1=274391&r2=274392&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1y-init-captures.cpp Fri Jul 1 17:27:16 2016 @@ -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}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits