r274392 - C++14 init-capture: error out instead of crashing.

Manman Ren via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 1 15:27:16 PDT 2016


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}}
+}
+}




More information about the cfe-commits mailing list