[cfe-commits] r90809 - in /cfe/trunk: include/clang/Analysis/PathSensitive/AnalysisContext.h include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/GRState.h include/clang/Analysis/PathSensitive/MemRegion.h include/clang/Analysis/PathSensitive/Store.h lib/Analysis/AnalysisContext.cpp lib/Analysis/BasicStore.cpp lib/Analysis/CFRefCount.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp lib/Analysis/Store.cpp lib/Analysis/ValueManager.cpp

Ted Kremenek kremenek at apple.com
Mon Dec 7 14:05:27 PST 2009


Author: kremenek
Date: Mon Dec  7 16:05:27 2009
New Revision: 90809

URL: http://llvm.org/viewvc/llvm-project?rev=90809&view=rev
Log:
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).

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
    cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
    cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
    cfe/trunk/lib/Analysis/AnalysisContext.cpp
    cfe/trunk/lib/Analysis/BasicStore.cpp
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/MemRegion.cpp
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/lib/Analysis/Store.cpp
    cfe/trunk/lib/Analysis/ValueManager.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/AnalysisContext.h Mon Dec  7 16:05:27 2009
@@ -32,7 +32,8 @@
 class ImplicitParamDecl;
 class LocationContextManager;
 class BlockDataRegion;
-
+class StackFrameContext;
+  
 /// AnalysisContext contains the context data for the function or method under
 /// analysis.
 class AnalysisContext {
@@ -117,6 +118,8 @@
   const ImplicitParamDecl *getSelfDecl() const {
     return Ctx->getSelfDecl();
   }
+  
+  const StackFrameContext *getCurrentStackFrame() const;
 
   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
 

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Mon Dec  7 16:05:27 2009
@@ -281,6 +281,13 @@
   void VisitDeclRefExpr(DeclRefExpr* DR, ExplodedNode* Pred,
                         ExplodedNodeSet& Dst, bool asLValue);
 
+  /// VisitBlockDeclRefExpr - Transfer function logic for BlockDeclRefExprs.
+  void VisitBlockDeclRefExpr(BlockDeclRefExpr* DR, ExplodedNode* Pred,
+                             ExplodedNodeSet& Dst, bool asLValue);
+  
+  void VisitCommonDeclRefExpr(Expr* DR, const NamedDecl *D,ExplodedNode* Pred,
+                             ExplodedNodeSet& Dst, bool asLValue);  
+  
   /// VisitDeclStmt - Transfer function logic for DeclStmts.
   void VisitDeclStmt(DeclStmt* DS, ExplodedNode* Pred, ExplodedNodeSet& Dst);
 

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Mon Dec  7 16:05:27 2009
@@ -217,6 +217,7 @@
   ///  for the compound literal and 'BegInit' and 'EndInit' represent an
   ///  array of initializer values.
   const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
+                                     const LocationContext *LC,
                                      SVal V) const;
 
   const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
@@ -237,7 +238,8 @@
   /// Get the lvalue for a StringLiteral.
   SVal getLValue(const StringLiteral *literal) const;
 
-  SVal getLValue(const CompoundLiteralExpr *literal) const;
+  SVal getLValue(const CompoundLiteralExpr *literal,
+                 const LocationContext *LC) const;
 
   /// Get the lvalue for an ivar reference.
   SVal getLValue(const ObjCIvarDecl *decl, SVal base) const;
@@ -609,9 +611,10 @@
                            cast<DefinedSVal>(UpperBound), Assumption);
 }
 
-inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
-                                            SVal V) const {
-  return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, V);
+inline const GRState *
+GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
+                             const LocationContext *LC, SVal V) const {
+  return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, LC, V);
 }
 
 inline const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const {
@@ -639,8 +642,9 @@
   return getStateManager().StoreMgr->getLValueString(literal);
 }
 
-inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const {
-  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal);
+inline SVal GRState::getLValue(const CompoundLiteralExpr *literal,
+                               const LocationContext *LC) const {
+  return getStateManager().StoreMgr->getLValueCompoundLiteral(literal, LC);
 }
 
 inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Mon Dec  7 16:05:27 2009
@@ -35,6 +35,7 @@
 class MemRegionManager;
 class MemSpaceRegion;
 class LocationContext;
+class StackFrameContext;
 class VarRegion;
 
 //===----------------------------------------------------------------------===//
@@ -45,22 +46,36 @@
 class MemRegion : public llvm::FoldingSetNode {
   friend class MemRegionManager;
 public:
-  enum Kind { MemSpaceRegionKind,
-              SymbolicRegionKind,
-              AllocaRegionKind,
-              // Typed regions.
-              BEG_TYPED_REGIONS,
-               FunctionTextRegionKind,
-               BlockTextRegionKind,
-               BlockDataRegionKind,
-               CompoundLiteralRegionKind,
-               StringRegionKind, ElementRegionKind,
-               // Decl Regions.
-                 BEG_DECL_REGIONS,
-                  VarRegionKind, FieldRegionKind,
-                  ObjCIvarRegionKind, ObjCObjectRegionKind,
-                 END_DECL_REGIONS,
-              END_TYPED_REGIONS };
+  enum Kind {
+    // Memory spaces.
+    BEG_MEMSPACES,
+    GenericMemSpaceRegionKind = BEG_MEMSPACES,
+    StackLocalsSpaceRegionKind,
+    StackArgumentsSpaceRegionKind,
+    HeapSpaceRegionKind,
+    GlobalsSpaceRegionKind,
+    END_MEMSPACES = GlobalsSpaceRegionKind,
+    // Untyped regions.
+    SymbolicRegionKind,
+    AllocaRegionKind,
+    // Typed regions.
+    BEG_TYPED_REGIONS,
+    FunctionTextRegionKind = BEG_TYPED_REGIONS,
+    BlockTextRegionKind,
+    BlockDataRegionKind,
+    CompoundLiteralRegionKind,
+    StringRegionKind,
+    ElementRegionKind,
+    // Decl Regions.
+    BEG_DECL_REGIONS,
+    VarRegionKind = BEG_DECL_REGIONS,
+    FieldRegionKind,
+    ObjCIvarRegionKind,
+    ObjCObjectRegionKind,
+    END_DECL_REGIONS = ObjCObjectRegionKind,
+    END_TYPED_REGIONS = END_DECL_REGIONS
+  };
+    
 private:
   const Kind kind;
 
@@ -111,25 +126,92 @@
 /// MemSpaceRegion - A memory region that represents and "memory space";
 ///  for example, the set of global variables, the stack frame, etc.
 class MemSpaceRegion : public MemRegion {
-  friend class MemRegionManager;
-
 protected:
+  friend class MemRegionManager;
+  
   MemRegionManager *Mgr;
 
-  MemSpaceRegion(MemRegionManager *mgr) : MemRegion(MemSpaceRegionKind),
-                                          Mgr(mgr) {}
+  MemSpaceRegion(MemRegionManager *mgr, Kind k = GenericMemSpaceRegionKind)
+    : MemRegion(k), Mgr(mgr) {
+    assert(classof(this));
+  }
+
+  MemRegionManager* getMemRegionManager() const { return Mgr; }
 
-  MemRegionManager* getMemRegionManager() const {
-    return Mgr;
+public:
+  bool isBoundable() const { return false; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= BEG_MEMSPACES && k <= END_MEMSPACES;
   }
+};
+  
+class GlobalsSpaceRegion : public MemSpaceRegion {
+  friend class MemRegionManager;
 
+  GlobalsSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, GlobalsSpaceRegionKind) {}
 public:
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == GlobalsSpaceRegionKind;
+  }
+};
+  
+class HeapSpaceRegion : public MemSpaceRegion {
+  friend class MemRegionManager;
+  
+  HeapSpaceRegion(MemRegionManager *mgr)
+    : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == HeapSpaceRegionKind;
+  }
+};
+  
+class StackSpaceRegion : public MemSpaceRegion {
+private:
+  const StackFrameContext *SFC;
 
-  bool isBoundable() const { return false; }
+protected:
+  StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
+    : MemSpaceRegion(mgr, k), SFC(sfc) {
+    assert(classof(this));
+  }
 
-  static bool classof(const MemRegion* R) {
-    return R->getKind() == MemSpaceRegionKind;
+public:  
+  const StackFrameContext *getStackFrame() const { return SFC; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const;
+
+  static bool classof(const MemRegion *R) {
+    Kind k = R->getKind();
+    return k >= StackLocalsSpaceRegionKind &&
+           k <= StackArgumentsSpaceRegionKind;
+  }  
+};
+  
+class StackLocalsSpaceRegion : public StackSpaceRegion {
+private:
+  friend class MemRegionManager;
+  StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackLocalsSpaceRegionKind;
+  }
+};
+
+class StackArgumentsSpaceRegion : public StackSpaceRegion {
+private:
+  friend class MemRegionManager;
+  StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
+    : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
+public:
+  static bool classof(const MemRegion *R) {
+    return R->getKind() == StackArgumentsSpaceRegionKind;
   }
 };
 
@@ -149,7 +231,7 @@
   bool isSubRegionOf(const MemRegion* R) const;
 
   static bool classof(const MemRegion* R) {
-    return R->getKind() > MemSpaceRegionKind;
+    return R->getKind() > END_MEMSPACES;
   }
 };
 
@@ -237,7 +319,7 @@
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
-    return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
+    return k >= BEG_TYPED_REGIONS && k <= END_TYPED_REGIONS;
   }
 };
 
@@ -295,12 +377,17 @@
 ///  like a closure a block captures the values of externally referenced
 ///  variables.
 class BlockTextRegion : public CodeTextRegion {
+  friend class MemRegionManager;
+
   const BlockDecl *BD;
+  AnalysisContext *AC;
   CanQualType locTy;
-public:  
-  BlockTextRegion(const BlockDecl *bd, CanQualType lTy, const MemRegion* sreg)
-    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), locTy(lTy) {}
-  
+
+  BlockTextRegion(const BlockDecl *bd, CanQualType lTy,
+                  AnalysisContext *ac, const MemRegion* sreg)
+    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+
+public:
   QualType getLocationType(ASTContext &C) const {
     return locTy;
   }
@@ -308,13 +395,16 @@
   const BlockDecl *getDecl() const {
     return BD;
   }
+
+  AnalysisContext *getAnalysisContext() const { return AC; }
     
   virtual void dumpToStream(llvm::raw_ostream& os) const;
   
   void Profile(llvm::FoldingSetNodeID& ID) const;
   
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
-                            CanQualType, const MemRegion*);
+                            CanQualType, const AnalysisContext*,
+                            const MemRegion*);
   
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockTextRegionKind;
@@ -329,15 +419,16 @@
 ///  variables.
 /// BlockDataRegion - A region that represents code texts of blocks (closures).
 class BlockDataRegion : public SubRegion {
+  friend class MemRegionManager;
   const BlockTextRegion *BC;
-  const LocationContext *LC;
+  const LocationContext *LC; // Can be null */
   void *ReferencedVars;
-public:  
-  BlockDataRegion(const BlockTextRegion *bc, 
-                  const LocationContext *lc,
+
+  BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
                   const MemRegion *sreg)
   : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {}
 
+public:  
   const BlockTextRegion *getCodeRegion() const { return BC; }
   
   const BlockDecl *getDecl() const { return BC->getDecl(); }
@@ -374,9 +465,8 @@
     
   void Profile(llvm::FoldingSetNodeID& ID) const;
     
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID,
-                            const BlockTextRegion *BC,
-                            const LocationContext *LC, const MemRegion *);
+  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
+                            const LocationContext *, const MemRegion *);
     
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockDataRegionKind;
@@ -499,25 +589,20 @@
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
-    return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS;
+    return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
   }
 };
 
 class VarRegion : public DeclRegion {
   friend class MemRegionManager;
 
-  // Data.
-  const LocationContext *LC;
-
   // Constructors and private methods.
-  VarRegion(const VarDecl* vd, const LocationContext *lC, const MemRegion* sReg)
-    : DeclRegion(vd, sReg, VarRegionKind), LC(lC) {}
+  VarRegion(const VarDecl* vd, const MemRegion* sReg)
+    : DeclRegion(vd, sReg, VarRegionKind) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD,
-                            const LocationContext *LC,
                             const MemRegion *superRegion) {
     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
-    ID.AddPointer(LC);
   }
 
   void Profile(llvm::FoldingSetNodeID& ID) const;
@@ -525,8 +610,6 @@
 public:
   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
 
-  const LocationContext *getLocationContext() const { return LC; }
-
   QualType getValueType(ASTContext& C) const {
     // FIXME: We can cache this if needed.
     return C.getCanonicalType(getDecl()->getType());
@@ -673,16 +756,16 @@
   llvm::BumpPtrAllocator& A;
   llvm::FoldingSet<MemRegion> Regions;
 
-  MemSpaceRegion *globals;
-  MemSpaceRegion *stack;
-  MemSpaceRegion *stackArguments;
-  MemSpaceRegion *heap;
+  GlobalsSpaceRegion *globals;
+  StackLocalsSpaceRegion *stackLocals;
+  StackArgumentsSpaceRegion *stackArguments;
+  HeapSpaceRegion *heap;
   MemSpaceRegion *unknown;
   MemSpaceRegion *code;
 
 public:
   MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
-    : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0),
+    : C(c), A(a), globals(0), stackLocals(0), stackArguments(0), heap(0),
       unknown(0), code(0) {}
 
   ~MemRegionManager();
@@ -691,21 +774,23 @@
   
   llvm::BumpPtrAllocator &getAllocator() { return A; }
 
-  /// getStackRegion - Retrieve the memory region associated with the
-  ///  current stack frame.
-  const MemSpaceRegion *getStackRegion();
+  /// getStackLocalsRegion - Retrieve the memory region associated with the
+  ///  specified stack frame.
+  const StackLocalsSpaceRegion *
+  getStackLocalsRegion(const StackFrameContext *STC);
 
   /// getStackArgumentsRegion - Retrieve the memory region associated with
-  ///  function/method arguments of the current stack frame.
-  const MemSpaceRegion *getStackArgumentsRegion();
+  ///  function/method arguments of the specified stack frame.
+  const StackArgumentsSpaceRegion *
+  getStackArgumentsRegion(const StackFrameContext *STC);
 
   /// getGlobalsRegion - Retrieve the memory region associated with
   ///  all global variables.
-  const MemSpaceRegion *getGlobalsRegion();
+  const GlobalsSpaceRegion *getGlobalsRegion();
 
   /// getHeapRegion - Retrieve the memory region associated with the
   ///  generic "heap".
-  const MemSpaceRegion *getHeapRegion();
+  const HeapSpaceRegion *getHeapRegion();
 
   /// getUnknownRegion - Retrieve the memory region associated with unknown
   /// memory space.
@@ -714,12 +799,14 @@
   const MemSpaceRegion *getCodeRegion();
 
   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
-  const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt);
+  const AllocaRegion *getAllocaRegion(const Expr* Ex, unsigned Cnt,
+                                      const LocationContext *LC);
 
   /// getCompoundLiteralRegion - Retrieve the region associated with a
   ///  given CompoundLiteral.
   const CompoundLiteralRegion*
-  getCompoundLiteralRegion(const CompoundLiteralExpr* CL);
+  getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
+                           const LocationContext *LC);
 
   /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
   const SymbolicRegion* getSymbolicRegion(SymbolRef sym);
@@ -730,6 +817,10 @@
   ///  a specified VarDecl and LocationContext.
   const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC);
 
+  /// getVarRegion - Retrieve or create the memory region associated with
+  ///  a specified VarDecl and super region.
+  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
+  
   /// getElementRegion - Retrieve the memory region associated with the
   ///  associated element type, index, and super region.
   const ElementRegion *getElementRegion(QualType elementType, SVal Idx,
@@ -768,9 +859,15 @@
 
   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,
-                                            CanQualType locTy);
+                                            CanQualType locTy,
+                                            AnalysisContext *AC);
+  
+  /// getBlockDataRegion - Get the memory region associated with an instance
+  ///  of a block.  Unlike many other MemRegions, the LocationContext*
+  ///  argument is allowed to be NULL for cases where we have no known
+  ///  context.
   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
-                                      const LocationContext *lc);
+                                            const LocationContext *lc = NULL);
 
   bool isGlobalsRegion(const MemRegion* R) {
     assert(R);
@@ -791,7 +888,15 @@
   RegionTy* getSubRegion(const A1 a1, const A2 a2,
                          const MemRegion* superRegion);
 
-  const MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region);
+  template <typename RegionTy, typename A1, typename A2, typename A3>
+  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
+                         const MemRegion* superRegion);
+  
+  template <typename REG>
+  const REG* LazyAllocate(REG*& region);
+  
+  template <typename REG, typename ARG>
+  const REG* LazyAllocate(REG*& region, ARG a);
 };
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Mon Dec  7 16:05:27 2009
@@ -73,8 +73,9 @@
   ///  for the compound literal and 'BegInit' and 'EndInit' represent an
   ///  array of initializer values.
   virtual const GRState *BindCompoundLiteral(const GRState *state,
-                                              const CompoundLiteralExpr* cl,
-                                              SVal v) = 0;
+                                             const CompoundLiteralExpr* cl,
+                                             const LocationContext *LC,
+                                             SVal v) = 0;
 
   /// getInitialStore - Returns the initial "empty" store representing the
   ///  value bindings upon entry to an analyzed function.
@@ -93,7 +94,8 @@
 
   virtual SVal getLValueString(const StringLiteral* sl) = 0;
 
-  virtual SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl) = 0;
+  SVal getLValueCompoundLiteral(const CompoundLiteralExpr* cl,
+                                const LocationContext *LC);
 
   virtual SVal getLValueIvar(const ObjCIvarDecl* decl, SVal base) = 0;
 

Modified: cfe/trunk/lib/Analysis/AnalysisContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisContext.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisContext.cpp Mon Dec  7 16:05:27 2009
@@ -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.
 //===----------------------------------------------------------------------===//
 

Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Mon Dec  7 16:05:27 2009
@@ -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())

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Mon Dec  7 16:05:27 2009
@@ -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);
 }
 

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Dec  7 16:05:27 2009
@@ -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));
   }

Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Mon Dec  7 16:05:27 2009
@@ -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 <> 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();
+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);
   }
-};
+  
+  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 StackLocalsSpaceRegion*
+MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {  
+  return LazyAllocate(stackLocals, STC);
 }
 
-const MemSpaceRegion *MemRegionManager::getStackArgumentsRegion() {
-  return LazyAllocate(stackArguments);
+const StackArgumentsSpaceRegion *
+MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
+  return LazyAllocate(stackArguments, STC);
 }
 
-const MemSpaceRegion *MemRegionManager::getGlobalsRegion() {
+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();
+
+    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);
+}
 
-  return getRegion<VarRegion>(D, LC);
+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;
 }

Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Dec  7 16:05:27 2009
@@ -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,

Modified: cfe/trunk/lib/Analysis/Store.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Store.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/Store.cpp (original)
+++ cfe/trunk/lib/Analysis/Store.cpp Mon Dec  7 16:05:27 2009
@@ -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

Modified: cfe/trunk/lib/Analysis/ValueManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ValueManager.cpp?rev=90809&r1=90808&r2=90809&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/ValueManager.cpp (original)
+++ cfe/trunk/lib/Analysis/ValueManager.cpp Mon Dec  7 16:05:27 2009
@@ -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);
 }





More information about the cfe-commits mailing list