Index: test/SemaCXX/blocks-and-lambdas.cpp
===================================================================
--- test/SemaCXX/blocks-and-lambdas.cpp	(revision 0)
+++ test/SemaCXX/blocks-and-lambdas.cpp	(revision 0)
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks -std=c++11
+
+// PR 12746
+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();
+  }
+}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 156351)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -2679,12 +2679,14 @@
   bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
                           SourceLocation EllipsisLoc, bool BuildAndDiagnose, 
                           QualType &CaptureType,
-                          QualType &DeclRefType);
+                          QualType &DeclRefType,
+                          bool isEnclosingLocal = false);
 
   /// \brief Try to capture the given variable.
   bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
                           TryCaptureKind Kind = TryCapture_Implicit,
-                          SourceLocation EllipsisLoc = SourceLocation());
+                          SourceLocation EllipsisLoc = SourceLocation(),
+                          bool isEnclosingLocal = false);
   
   /// \brief Given a variable, determine the type that a reference to that
   /// variable will have in the given scope.
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 156351)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -10023,7 +10023,8 @@
 static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
                                   VarDecl *Var, QualType FieldType, 
                                   QualType DeclRefType,
-                                  SourceLocation Loc) {
+                                  SourceLocation Loc,
+                                  bool isEnclosingLocal) {
   CXXRecordDecl *Lambda = LSI->Lambda;
 
   // Build the non-static data member.
@@ -10052,7 +10053,7 @@
   // 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, false, DeclRefType,
+  Expr *Ref = new (S.Context) DeclRefExpr(Var, isEnclosingLocal, DeclRefType,
                                           VK_LValue, Loc);
   Var->setReferenced(true);
   Var->setUsed(true);
@@ -10143,7 +10144,8 @@
                               TryCaptureKind Kind, SourceLocation EllipsisLoc,
                               bool BuildAndDiagnose, 
                               QualType &CaptureType,
-                              QualType &DeclRefType) {
+                              QualType &DeclRefType,
+                              bool isEnclosingLocal) {
   bool Nested = false;
   
   DeclContext *DC = CurContext;
@@ -10396,7 +10398,7 @@
     Expr *CopyExpr = 0;
     if (BuildAndDiagnose) {
       ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType,
-                                          DeclRefType, Loc);
+                                          DeclRefType, Loc, isEnclosingLocal);
       if (!Result.isInvalid())
         CopyExpr = Result.take();
     }
@@ -10426,12 +10428,13 @@
 }
 
 bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
-                              TryCaptureKind Kind, SourceLocation EllipsisLoc) {  
+                              TryCaptureKind Kind, SourceLocation EllipsisLoc,
+                              bool isEnclosingLocal) {  
   QualType CaptureType;
   QualType DeclRefType;
   return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc,
                             /*BuildAndDiagnose=*/true, CaptureType,
-                            DeclRefType);
+                            DeclRefType, isEnclosingLocal);
 }
 
 QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {
@@ -10447,7 +10450,8 @@
 }
 
 static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var,
-                               SourceLocation Loc) {
+                               SourceLocation Loc,
+                               bool isEnclosingLocal = false) {
   // Keep track of used but undefined variables.
   // FIXME: We shouldn't suppress this warning for static data members.
   if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
@@ -10457,7 +10461,8 @@
     if (old.isInvalid()) old = Loc;
   }
 
-  SemaRef.tryCaptureVariable(Var, Loc);
+  SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit,
+                             SourceLocation(), isEnclosingLocal);
 
   Var->setUsed(true);
 }
@@ -10552,8 +10557,12 @@
       Var->isUsableInConstantExpressions(SemaRef.Context) &&
       Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE())
     SemaRef.MaybeODRUseExprs.insert(E);
-  else
-    MarkVarDeclODRUsed(SemaRef, Var, Loc);
+  else {
+    bool isEnclosingLocal = false;
+    if (E && isa<DeclRefExpr>(E))
+      isEnclosingLocal = cast<DeclRefExpr>(E)->refersToEnclosingLocal();
+    MarkVarDeclODRUsed(SemaRef, Var, Loc, isEnclosingLocal);
+  }
 }
 
 /// \brief Mark a variable referenced, and check whether it is odr-used
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp	(revision 156351)
+++ lib/CodeGen/CGBlocks.cpp	(working copy)
@@ -698,7 +698,7 @@
     // Compute the address of the thing we're going to move into the
     // block literal.
     llvm::Value *src;
-    if (ci->isNested()) {
+    if (BlockInfo && ci->isNested()) {
       // We need to use the capture from the enclosing block.
       const CGBlockInfo::Capture &enclosingCapture =
         BlockInfo->getCapture(variable);
