]> granicus.if.org Git - clang/commitdiff
When computing the type of a local variable reference within a lambda,
authorDouglas Gregor <dgregor@apple.com>
Wed, 8 Feb 2012 20:56:50 +0000 (20:56 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 8 Feb 2012 20:56:50 +0000 (20:56 +0000)
only add 'const' for variables captured by copy in potentially
evaluated expressions of non-mutable lambdas. (The "by copy" part was
missing).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150088 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/p7.cpp

index bbf992c21987e9673dce8ed1cb40ba3167a01e9c..accf85171eef099a06167e8421391d40bfcebf68 100644 (file)
@@ -2094,6 +2094,15 @@ static bool shouldBuildBlockDeclRef(ValueDecl *D, Sema &S) {
   return S.getCurBlock() != 0;
 }
 
+/// \brief Determine whether the given lambda would capture the given
+/// variable by copy.
+static bool willCaptureByCopy(LambdaScopeInfo *LSI, VarDecl *Var) {
+  if (LSI->isCaptured(Var))
+    return LSI->getCapture(Var).isCopyCapture();
+
+  return LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval;
+}
+
 static bool shouldAddConstQualToVarRef(ValueDecl *D, Sema &S) {
   VarDecl *var = dyn_cast<VarDecl>(D);
   if (!var)
@@ -2117,7 +2126,8 @@ static bool shouldAddConstQualToVarRef(ValueDecl *D, Sema &S) {
   // about decltype hints that it might apply in unevaluated contexts
   // as well... and there's precent in our blocks implementation.
   return !LSI->Mutable &&
-         S.ExprEvalContexts.back().Context != Sema::Unevaluated;
+         S.ExprEvalContexts.back().Context != Sema::Unevaluated &&
+         willCaptureByCopy(LSI, var);
 }
 
 static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD,
index 239b6d4f469f83973f2a7b1c5a5464c33572a194..0696f603b683511b75d4ed66ace1472b77288d29 100644 (file)
@@ -6,7 +6,40 @@ void analysis_based_warnings() {
   // expected-error{{lambda expressions are not supported yet}}
 }
 
-// FIXME: Also check translation of captured vars to data members,
-// most of which isn't in the AST.
+// Check that we get the right types of captured variables (the semantic-analysis part of 
+int &check_const_int(int&);
+float &check_const_int(const int&);
+
+void test_capture_constness(int i, const int ic) {
+  [i,ic] ()->void { // expected-error{{lambda expressions are not supported yet}}
+    float &fr1 = check_const_int(i);
+    float &fr2 = check_const_int(ic);
+  }; 
+
+  [=] ()->void { // expected-error{{lambda expressions are not supported yet}}
+    float &fr1 = check_const_int(i);
+    float &fr2 = check_const_int(ic);
+  }; 
+
+  [i,ic] () mutable ->void { // expected-error{{lambda expressions are not supported yet}}
+    int &ir = check_const_int(i);
+    float &fr = check_const_int(ic);
+  };
+
+  [=] () mutable ->void { // expected-error{{lambda expressions are not supported yet}}
+    int &ir = check_const_int(i);
+    float &fr = check_const_int(ic);
+  };
+
+  [&i,&ic] ()->void { // expected-error{{lambda expressions are not supported yet}}
+    int &ir = check_const_int(i);
+    float &fr = check_const_int(ic);
+  };
+
+  [&] ()->void { // expected-error{{lambda expressions are not supported yet}}
+    int &ir = check_const_int(i);
+    float &fr = check_const_int(ic);
+  };
+}