]> granicus.if.org Git - clang/commitdiff
Clean up r156925, so that we only mark the capturing DeclRefExpr of a
authorDouglas Gregor <dgregor@apple.com>
Wed, 16 May 2012 17:01:33 +0000 (17:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 16 May 2012 17:01:33 +0000 (17:01 +0000)
lambda as referring to a local in an enclosing scope if we're in the
enclosing scope of the lambda (not it's function call operator). Also,
turn the test into an IR generation test, since that's where the
crashes occurred. Really fixes PR12746 / <rdar://problem/11465120>.

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

lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm [new file with mode: 0644]
test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm

index 440382bb5a353611c44cc39d3e87a902940866c1..67b60fad519049e61b37f0b9eed6059ead57b288 100644 (file)
@@ -10040,7 +10040,8 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc,
 static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
                                   VarDecl *Var, QualType FieldType, 
                                   QualType DeclRefType,
-                                  SourceLocation Loc) {
+                                  SourceLocation Loc,
+                                  bool RefersToEnclosingLocal) {
   CXXRecordDecl *Lambda = LSI->Lambda;
 
   // Build the non-static data member.
@@ -10069,8 +10070,8 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
   // C++ [expr.prim.labda]p12:
   //   An entity captured by a lambda-expression is odr-used (3.2) in
   //   the scope containing the lambda-expression.
-  Expr *Ref = new (S.Context) DeclRefExpr(Var, true, DeclRefType,
-                                          VK_LValue, Loc);
+  Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, 
+                                          DeclRefType, VK_LValue, Loc);
   Var->setReferenced(true);
   Var->setUsed(true);
 
@@ -10413,7 +10414,8 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
     Expr *CopyExpr = 0;
     if (BuildAndDiagnose) {
       ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType,
-                                          DeclRefType, Loc);
+                                          DeclRefType, Loc,
+                                          I == N-1);
       if (!Result.isInvalid())
         CopyExpr = Result.take();
     }
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
new file mode 100644 (file)
index 0000000..9adecd0
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -fblocks -emit-llvm -o - -triple x86_64-apple-darwin11.3 %s | FileCheck %s
+
+namespace PR12746 {
+  // CHECK: define zeroext i1 @_ZN7PR127462f1EPi
+  bool f1(int *x) {
+    // CHECK: store i8* bitcast (i1 (i8*)* @__f1_block_invoke_0 to i8*)
+    bool (^outer)() = ^ {
+      auto inner = [&]() -> bool {
+       return x == 0;
+      };
+      return inner();
+    };
+    return outer();
+  }
+
+  // CHECK: define internal zeroext i1 @__f1_block_invoke_0
+  // CHECK: call zeroext i1 @"_ZNK7PR127462f119__f1_block_invoke_03$_0clEv"
+
+  bool f2(int *x) {
+    auto outer = [&]() -> bool {
+      bool (^inner)() = ^ {
+       return x == 0;
+      };
+      return inner();
+    };
+    return outer();
+  }
+}
+
index 941443a0d6846c34d2089f218957f13167d0a335..0c3fdb2d80eb39cc020661b0b71cc560d2d7765d 100644 (file)
@@ -86,25 +86,3 @@ namespace overloading {
     int &ir = accept_lambda_conv([](int x) { return x + 1; });
   }
 }
-
-namespace PR12746 {
-  bool f1(int *x) {
-    bool (^outer)() = ^ {
-      auto inner = [&]() -> bool {
-       return x == 0;
-      };
-      return inner();
-    };
-    return outer();
-  }
-
-  bool f2(int *x) {
-    auto outer = [&]() -> bool {
-      bool (^inner)() = ^ {
-       return x == 0;
-      };
-      return inner();
-    };
-    return outer();
-  }
-}