Add analysis support for blocks.  This includes a few key changes:

- Refactor the MemRegion hierarchy to distinguish between different StackSpaceRegions for locals and parameters.
- VarRegions for "captured" variables now have the BlockDataRegion as their super region (except those passed by reference)
- Add transfer function support to GRExprEngine for BlockDeclRefExprs.

This change also supports analyzing blocks as an analysis entry point
(top-of-the-stack), which required pushing more context-sensitivity
around in the MemRegion hierarchy via the use of LocationContext
objects.  Functionally almost everything is the same, except we track
LocationContexts in a few more areas and StackSpaceRegions now refer
to a StackFrameContext object.  In the future we will need to modify
MemRegionManager to allow multiple StackSpaceRegions in flight at once
(for the analysis of multiple stack frames).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90809 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index 6b74b52..113587f 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -166,6 +166,20 @@
 }
 
 //===----------------------------------------------------------------------===//
+// LocationContext methods.
+//===----------------------------------------------------------------------===//
+
+const StackFrameContext *LocationContext::getCurrentStackFrame() const {
+  const LocationContext *LC = this;
+  while (LC) {
+    if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
+      return SFC;
+    LC = LC->getParent();
+  }
+  return NULL;
+}
+
+//===----------------------------------------------------------------------===//
 // Lazily generated map to query the external variables referenced by a Block.
 //===----------------------------------------------------------------------===//
 
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index c2bf7a8..a38aaa7 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -68,14 +68,14 @@
   }
 
   const GRState *BindCompoundLiteral(const GRState *state,
-                                     const CompoundLiteralExpr* cl,
+                                     const CompoundLiteralExpr*,
+                                     const LocationContext*,
                                      SVal val) {
     return state;
   }
 
   SVal getLValueVar(const VarDecl *VD, const LocationContext *LC);
   SVal getLValueString(const StringLiteral *S);
-  SVal getLValueCompoundLiteral(const CompoundLiteralExpr *CL);
   SVal getLValueIvar(const ObjCIvarDecl* D, SVal Base);
   SVal getLValueField(const FieldDecl *D, SVal Base);
   SVal getLValueElement(QualType elementType, SVal Offset, SVal Base);
@@ -130,10 +130,6 @@
   return ValMgr.makeLoc(MRMgr.getStringRegion(S));
 }
 
-SVal BasicStoreManager::getLValueCompoundLiteral(const CompoundLiteralExpr* CL){
-  return ValMgr.makeLoc(MRMgr.getCompoundLiteralRegion(CL));
-}
-
 SVal BasicStoreManager::getLValueIvar(const ObjCIvarDecl* D, SVal Base) {
 
   if (Base.isUnknownOrUndef())
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 288645d..1df4f7c 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -3681,7 +3681,24 @@
   if (I == E)
     return;
   
-  state = state->scanReachableSymbols<StopTrackingCallback>(I, E).getState();
+  // FIXME: For now we invalidate the tracking of all symbols passed to blocks
+  // via captured variables, even though captured variables result in a copy
+  // and in implicit increment/decrement of a retain count.
+  llvm::SmallVector<const MemRegion*, 10> Regions;
+  const LocationContext *LC = C.getPredecessor()->getLocationContext();
+  MemRegionManager &MemMgr = C.getValueManager().getRegionManager();
+  
+  for ( ; I != E; ++I) {
+    const VarRegion *VR = *I;
+    if (VR->getSuperRegion() == R) {
+      VR = MemMgr.getVarRegion(VR->getDecl(), LC);
+    }
+    Regions.push_back(VR);
+  }
+  
+  state =
+    state->scanReachableSymbols<StopTrackingCallback>(Regions.data(),
+                                    Regions.data() + Regions.size()).getState();
   C.addTransition(state);
 }
 
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 57c645e..8f63128 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -473,6 +473,10 @@
     case Stmt::AsmStmtClass:
       VisitAsmStmt(cast<AsmStmt>(S), Pred, Dst);
       break;
+      
+    case Stmt::BlockDeclRefExprClass:
+      VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(S), Pred, Dst, false);
+      break;
 
     case Stmt::BlockExprClass:
       VisitBlockExpr(cast<BlockExpr>(S), Pred, Dst);
@@ -644,6 +648,10 @@
       VisitArraySubscriptExpr(cast<ArraySubscriptExpr>(Ex), Pred, Dst, true);
       return;
 
+    case Stmt::BlockDeclRefExprClass:
+      VisitBlockDeclRefExpr(cast<BlockDeclRefExpr>(Ex), Pred, Dst, true);
+      return;
+
     case Stmt::DeclRefExprClass:
       VisitDeclRefExpr(cast<DeclRefExpr>(Ex), Pred, Dst, true);
       return;
@@ -1135,9 +1143,20 @@
 
 void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
                                     ExplodedNodeSet &Dst, bool asLValue) {
+  VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
+}
+
+void GRExprEngine::VisitBlockDeclRefExpr(BlockDeclRefExpr *Ex,
+                                         ExplodedNode *Pred,
+                                    ExplodedNodeSet &Dst, bool asLValue) {
+  VisitCommonDeclRefExpr(Ex, Ex->getDecl(), Pred, Dst, asLValue);
+}
+
+void GRExprEngine::VisitCommonDeclRefExpr(Expr *Ex, const NamedDecl *D,
+                                          ExplodedNode *Pred,
+                                          ExplodedNodeSet &Dst, bool asLValue) {
 
   const GRState *state = GetState(Pred);
-  const NamedDecl *D = Ex->getDecl();
 
   if (const VarDecl* VD = dyn_cast<VarDecl>(D)) {
 
@@ -1566,7 +1585,8 @@
     // FIXME: Refactor into StoreManager itself?
     MemRegionManager& RM = getStateManager().getRegionManager();
     const MemRegion* R =
-      RM.getAllocaRegion(CE, Builder->getCurrentBlockCount());
+      RM.getAllocaRegion(CE, Builder->getCurrentBlockCount(),
+                         Pred->getLocationContext());
 
     // Set the extent of the region in bytes. This enables us to use the
     // SVal of the argument directly. If we save the extent in bits, we
@@ -2064,10 +2084,12 @@
   for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I!=EI; ++I) {
     const GRState* state = GetState(*I);
     SVal ILV = state->getSVal(ILE);
-    state = state->bindCompoundLiteral(CL, ILV);
+    const LocationContext *LC = (*I)->getLocationContext();
+    state = state->bindCompoundLiteral(CL, LC, ILV);
 
-    if (asLValue)
-      MakeNode(Dst, CL, *I, state->BindExpr(CL, state->getLValue(CL)));
+    if (asLValue) {
+      MakeNode(Dst, CL, *I, state->BindExpr(CL, state->getLValue(CL, LC)));
+    }
     else
       MakeNode(Dst, CL, *I, state->BindExpr(CL, ILV));
   }
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index 2eb9d8e..3bf3e5b 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -106,75 +106,24 @@
   return R;
 }
 
-//===----------------------------------------------------------------------===//
-// Traits for constructing regions.
-//===----------------------------------------------------------------------===//
-
-template <> struct MemRegionManagerTrait<AllocaRegion> {
-  typedef MemRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             const Expr *, unsigned) {
-    return MRMgr.getStackRegion();
+template <typename RegionTy, typename A1, typename A2, typename A3>
+RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+                                         const MemRegion *superRegion) {
+  
+  llvm::FoldingSetNodeID ID;
+  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
+  void* InsertPos;
+  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
+                                                                   InsertPos));
+  
+  if (!R) {
+    R = (RegionTy*) A.Allocate<RegionTy>();
+    new (R) RegionTy(a1, a2, a3, superRegion);
+    Regions.InsertNode(R, InsertPos);
   }
-};
-
-template <> struct MemRegionManagerTrait<CompoundLiteralRegion> {
-  typedef MemRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             const CompoundLiteralExpr *CL) {
-    
-    return CL->isFileScope() ? MRMgr.getGlobalsRegion()
-    : MRMgr.getStackRegion();
-  }
-};
-
-template <> struct MemRegionManagerTrait<StringRegion> {
-  typedef MemSpaceRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             const StringLiteral*) {
-    return MRMgr.getGlobalsRegion();
-  }
-};
-
-template <> struct MemRegionManagerTrait<VarRegion> {
-  typedef MemRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager &MRMgr,
-                                             const VarDecl *D,
-                                             const LocationContext *LC) {
-    
-    // FIXME: Make stack regions have a location context?
-    
-    if (D->hasLocalStorage()) {
-      return isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
-      ? MRMgr.getStackArgumentsRegion() : MRMgr.getStackRegion();
-    }
-    
-    return MRMgr.getGlobalsRegion();
-  }
-};
-
-template <> struct MemRegionManagerTrait<SymbolicRegion> {
-  typedef MemRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             SymbolRef) {
-    return MRMgr.getUnknownRegion();
-  }
-};
-
-template<> struct MemRegionManagerTrait<FunctionTextRegion> {
-  typedef MemSpaceRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             const FunctionDecl*) {
-    return MRMgr.getCodeRegion();
-  }
-};
-template<> struct MemRegionManagerTrait<BlockTextRegion> {
-  typedef MemSpaceRegion SuperRegionTy;
-  static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             const BlockDecl*, CanQualType) {
-    return MRMgr.getCodeRegion();
-  }
-};
+  
+  return R;
+}
 
 //===----------------------------------------------------------------------===//
 // Object destruction.
@@ -220,6 +169,11 @@
   ID.AddInteger((unsigned)getKind());
 }
 
+void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger((unsigned)getKind());
+  ID.AddPointer(getStackFrame());
+}
+
 void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                  const StringLiteral* Str,
                                  const MemRegion* superRegion) {
@@ -264,7 +218,7 @@
 }
 
 void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
-  VarRegion::ProfileRegion(ID, getDecl(), LC, superRegion);
+  VarRegion::ProfileRegion(ID, getDecl(), superRegion);
 }
 
 void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
@@ -303,27 +257,29 @@
 }
 
 void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
-                                   const BlockDecl *BD, CanQualType,
-                                   const MemRegion*) {
+                                    const BlockDecl *BD, CanQualType,
+                                    const AnalysisContext *AC,
+                                    const MemRegion*) {
   ID.AddInteger(MemRegion::BlockTextRegionKind);
   ID.AddPointer(BD);
 }
 
 void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
-  BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
+  BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
 }
 
 void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                     const BlockTextRegion *BC,
                                     const LocationContext *LC,
-                                    const MemRegion *) {
+                                    const MemRegion *sReg) {
   ID.AddInteger(MemRegion::BlockDataRegionKind);
   ID.AddPointer(BC);
   ID.AddPointer(LC);
+  ID.AddPointer(sReg);
 }
 
 void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
-  BlockDataRegion::ProfileRegion(ID, BC, LC, NULL);
+  BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
 }
 
 //===----------------------------------------------------------------------===//
@@ -404,28 +360,41 @@
 // MemRegionManager methods.
 //===----------------------------------------------------------------------===//
 
-const MemSpaceRegion *MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
+template <typename REG>
+const REG *MemRegionManager::LazyAllocate(REG*& region) {
   if (!region) {
-    region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
-    new (region) MemSpaceRegion(this);
+    region = (REG*) A.Allocate<REG>();
+    new (region) REG(this);
   }
 
   return region;
 }
 
-const MemSpaceRegion *MemRegionManager::getStackRegion() {
-  return LazyAllocate(stack);
+template <typename REG, typename ARG>
+const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
+  if (!region) {
+    region = (REG*) A.Allocate<REG>();
+    new (region) REG(this, a);
+  }
+  
+  return region;
 }
 
-const MemSpaceRegion *MemRegionManager::getStackArgumentsRegion() {
-  return LazyAllocate(stackArguments);
+const StackLocalsSpaceRegion*
+MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {  
+  return LazyAllocate(stackLocals, STC);
 }
 
-const MemSpaceRegion *MemRegionManager::getGlobalsRegion() {
+const StackArgumentsSpaceRegion *
+MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
+  return LazyAllocate(stackArguments, STC);
+}
+
+const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
   return LazyAllocate(globals);
 }
 
-const MemSpaceRegion *MemRegionManager::getHeapRegion() {
+const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
   return LazyAllocate(heap);
 }
 
@@ -442,36 +411,71 @@
 //===----------------------------------------------------------------------===//
 
 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
-  return getRegion<StringRegion>(Str);
+  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
 }
 
 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
                                                 const LocationContext *LC) {
+  const MemRegion *sReg = 0;
 
-  // FIXME: Once we implement scope handling, we will need to properly lookup
-  // 'D' to the proper LocationContext.  For now, just strip down to the
-  // StackFrame.
-  while (!isa<StackFrameContext>(LC))
-    LC = LC->getParent();
+  if (D->hasLocalStorage()) {
+    // FIXME: Once we implement scope handling, we will need to properly lookup
+    // 'D' to the proper LocationContext.
+    const StackFrameContext *STC = LC->getCurrentStackFrame();
 
-  return getRegion<VarRegion>(D, LC);
+    assert(STC);
+    sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
+           ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
+           : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
+  }
+  else {
+    sReg = getGlobalsRegion();
+  }
+  
+  return getSubRegion<VarRegion>(D, sReg);
+}
+
+const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
+                                                const MemRegion *superR) {
+  return getSubRegion<VarRegion>(D, superR);
 }
 
 const BlockDataRegion *
 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
                                      const LocationContext *LC) {
-  // FIXME: Once we implement scope handling, we will need to properly lookup
-  // 'D' to the proper LocationContext.  For now, just strip down to the
-  // StackFrame.
-  while (!isa<StackFrameContext>(LC))
-    LC = LC->getParent();
+  const MemRegion *sReg = 0;
   
-  return getSubRegion<BlockDataRegion>(BC, LC, getStackRegion());
+  if (LC) {    
+    // FIXME: Once we implement scope handling, we want the parent region
+    // to be the scope.  
+    const StackFrameContext *STC = LC->getCurrentStackFrame();
+    assert(STC);
+    sReg = getStackLocalsRegion(STC);
+  }
+  else {
+    // We allow 'LC' to be NULL for cases where want BlockDataRegions
+    // without context-sensitivity.
+    sReg = getUnknownRegion();
+  }
+
+  return getSubRegion<BlockDataRegion>(BC, LC, sReg);
 }
 
 const CompoundLiteralRegion*
-MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) {
-  return getRegion<CompoundLiteralRegion>(CL);
+MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
+                                           const LocationContext *LC) {
+  
+  const MemRegion *sReg = 0;
+  
+  if (CL->isFileScope())
+    sReg = getGlobalsRegion();
+  else {
+    const StackFrameContext *STC = LC->getCurrentStackFrame();
+    assert(STC);
+    sReg = getStackLocalsRegion(STC);
+  }
+  
+  return getSubRegion<CompoundLiteralRegion>(CL, sReg);
 }
 
 const ElementRegion*
@@ -499,18 +503,19 @@
 
 const FunctionTextRegion *
 MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
-  return getRegion<FunctionTextRegion>(FD);
+  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
 }
 
 const BlockTextRegion *
-MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy) {
-  return getRegion<BlockTextRegion>(BD, locTy);
+MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
+                                     AnalysisContext *AC) {
+  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
 }
 
 
 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
 const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
-  return getRegion<SymbolicRegion>(sym);
+  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
 }
 
 const FieldRegion *
@@ -532,8 +537,11 @@
 }
 
 const AllocaRegion*
-MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
-  return getRegion<AllocaRegion>(E, cnt);
+MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
+                                  const LocationContext *LC) {
+  const StackFrameContext *STC = LC->getCurrentStackFrame();
+  assert(STC);
+  return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
 }
 
 const MemSpaceRegion *MemRegion::getMemorySpace() const {
@@ -549,52 +557,30 @@
 }
 
 bool MemRegion::hasStackStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace()) {
-    MemRegionManager *Mgr = getMemRegionManager();
-    return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
-  }
-
-  return false;
+  return isa<StackSpaceRegion>(getMemorySpace());
 }
 
 bool MemRegion::hasHeapStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace())
-    return MS == getMemRegionManager()->getHeapRegion();
-
-  return false;
+  return isa<HeapSpaceRegion>(getMemorySpace());
 }
 
 bool MemRegion::hasHeapOrStackStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace()) {
-    MemRegionManager *Mgr = getMemRegionManager();
-    return MS == Mgr->getHeapRegion()
-      || MS == Mgr->getStackRegion()
-      || MS == Mgr->getStackArgumentsRegion();
-  }
-  return false;
+  const MemSpaceRegion *MS = getMemorySpace();
+  return isa<StackSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS);
 }
 
 bool MemRegion::hasGlobalsStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace())
-    return MS == getMemRegionManager()->getGlobalsRegion();
-
-  return false;
+  return isa<GlobalsSpaceRegion>(getMemorySpace());
 }
 
 bool MemRegion::hasParametersStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace())
-    return MS == getMemRegionManager()->getStackArgumentsRegion();
-
-  return false;
+  return isa<StackArgumentsSpaceRegion>(getMemorySpace());
 }
 
 bool MemRegion::hasGlobalsOrParametersStorage() const {
-  if (const MemSpaceRegion *MS = getMemorySpace()) {
-    MemRegionManager *Mgr = getMemRegionManager();
-    return MS == Mgr->getGlobalsRegion()
-    || MS == Mgr->getStackArgumentsRegion();
-  }
-  return false;
+  const MemSpaceRegion *MS = getMemorySpace();
+  return isa<StackArgumentsSpaceRegion>(MS) ||
+         isa<GlobalsSpaceRegion>(MS);
 }
 
 // getBaseRegion strips away all elements and fields, and get the base region
@@ -700,7 +686,7 @@
   if (ReferencedVars)
     return;
 
-  AnalysisContext *AC = LC->getAnalysisContext();
+  AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
   AnalysisContext::referenced_decls_iterator I, E;
   llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
   
@@ -717,8 +703,23 @@
   VarVec *BV = (VarVec*) A.Allocate<VarVec>();
   new (BV) VarVec(BC, E - I);
   
-  for ( ; I != E; ++I)
-    BV->push_back(MemMgr.getVarRegion(*I, LC), BC);
+  for ( ; I != E; ++I) {
+    const VarDecl *VD = *I;
+    const VarRegion *VR = 0;
+    
+    if (!VD->getAttr<BlocksAttr>())
+      VR = MemMgr.getVarRegion(VD, this);
+    else {
+      if (LC)
+        VR = MemMgr.getVarRegion(VD, LC);
+      else {
+        VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
+      }
+    }
+    
+    assert(VR);
+    BV->push_back(VR, BC);
+  }
   
   ReferencedVars = BV;
 }
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 4a84eea..c718f1f 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -287,7 +287,9 @@
   const GRState *Bind(const GRState *state, Loc LV, SVal V);
 
   const GRState *BindCompoundLiteral(const GRState *state,
-                                     const CompoundLiteralExpr* CL, SVal V);
+                                     const CompoundLiteralExpr* CL,
+                                     const LocationContext *LC,
+                                     SVal V);
 
   const GRState *BindDecl(const GRState *ST, const VarRegion *VR,
                           SVal InitVal);
@@ -615,15 +617,6 @@
   return loc::MemRegionVal(MRMgr.getVarRegion(VD, LC));
 }
 
-/// getLValueCompoundLiteral - Returns an SVal representing the lvalue
-///   of a compound literal.  Within RegionStore a compound literal
-///   has an associated region, and the lvalue of the compound literal
-///   is the lvalue of that region.
-SVal 
-RegionStoreManager::getLValueCompoundLiteral(const CompoundLiteralExpr* CL) {
-  return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL));
-}
-
 SVal RegionStoreManager::getLValueIvar(const ObjCIvarDecl* D, SVal Base) {
   return getLValueFieldOrIvar(D, Base);
 }
@@ -730,7 +723,11 @@
                                                            const MemRegion *R) {
 
   switch (R->getKind()) {
-    case MemRegion::MemSpaceRegionKind:
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind:
       assert(0 && "Cannot index into a MemSpace");
       return UnknownVal();
 
@@ -775,13 +772,6 @@
       // essentially are arrays of size 1.
       return ValMgr.makeIntVal(1, false);
     }
-
-    case MemRegion::BEG_DECL_REGIONS:
-    case MemRegion::END_DECL_REGIONS:
-    case MemRegion::BEG_TYPED_REGIONS:
-    case MemRegion::END_TYPED_REGIONS:
-      assert(0 && "Infeasible region");
-      return UnknownVal();
   }
 
   assert(0 && "Unreachable");
@@ -886,16 +876,13 @@
       // Technically this can happen if people do funny things with casts.
       return UnknownVal();
 
-    case MemRegion::MemSpaceRegionKind:
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind:
       assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
       return UnknownVal();
-
-    case MemRegion::BEG_DECL_REGIONS:
-    case MemRegion::END_DECL_REGIONS:
-    case MemRegion::BEG_TYPED_REGIONS:
-    case MemRegion::END_TYPED_REGIONS:
-      assert(0 && "Infeasible region");
-      return UnknownVal();
   }
 
   SVal Idx = ER->getIndex();
@@ -1462,9 +1449,11 @@
 // FIXME: this method should be merged into Bind().
 const GRState *
 RegionStoreManager::BindCompoundLiteral(const GRState *state,
-                                        const CompoundLiteralExpr* CL,
+                                        const CompoundLiteralExpr *CL,
+                                        const LocationContext *LC,
                                         SVal V) {
-  return Bind(state, loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL)), V);
+  return Bind(state, loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)),
+              V);
 }
 
 const GRState *RegionStoreManager::setImplicitDefaultValue(const GRState *state,
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 78eed46..e591842 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -77,11 +77,11 @@
 
   // Process region cast according to the kind of the region being cast.
   switch (R->getKind()) {
-    case MemRegion::BEG_TYPED_REGIONS:
-    case MemRegion::MemSpaceRegionKind:
-    case MemRegion::BEG_DECL_REGIONS:
-    case MemRegion::END_DECL_REGIONS:
-    case MemRegion::END_TYPED_REGIONS: {
+    case MemRegion::GenericMemSpaceRegionKind:
+    case MemRegion::StackLocalsSpaceRegionKind:
+    case MemRegion::StackArgumentsSpaceRegionKind:
+    case MemRegion::HeapSpaceRegionKind:
+    case MemRegion::GlobalsSpaceRegionKind: {
       assert(0 && "Invalid region cast");
       break;
     }
@@ -216,3 +216,16 @@
   
   return state;
 }
+
+//===----------------------------------------------------------------------===//
+// Common getLValueXXX methods.
+//===----------------------------------------------------------------------===//
+
+/// getLValueCompoundLiteral - Returns an SVal representing the lvalue
+///   of a compound literal.  Within RegionStore a compound literal
+///   has an associated region, and the lvalue of the compound literal
+///   is the lvalue of that region.
+SVal StoreManager::getLValueCompoundLiteral(const CompoundLiteralExpr* CL,
+                                            const LocationContext *LC) {
+  return loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC));
+}
\ No newline at end of file
diff --git a/lib/Analysis/ValueManager.cpp b/lib/Analysis/ValueManager.cpp
index 1e7a5fc..d091373 100644
--- a/lib/Analysis/ValueManager.cpp
+++ b/lib/Analysis/ValueManager.cpp
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/PathSensitive/ValueManager.h"
+#include "clang/Analysis/PathSensitive/AnalysisContext.h"
 
 using namespace clang;
 using namespace llvm;
@@ -144,7 +145,8 @@
 DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D,
                                           CanQualType locTy,
                                           const LocationContext *LC) {
-  const BlockTextRegion *BC = MemMgr.getBlockTextRegion(D, locTy);
+  const BlockTextRegion *BC =
+    MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext());
   const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
   return loc::MemRegionVal(BD);
 }