diff options
Diffstat (limited to 'lib/Analysis/MemRegion.cpp')
| -rw-r--r-- | lib/Analysis/MemRegion.cpp | 362 | 
1 files changed, 272 insertions, 90 deletions
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index af8bd16ee681..bc3a5b704552 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -22,6 +22,110 @@  using namespace clang;  //===----------------------------------------------------------------------===// +// MemRegion Construction. +//===----------------------------------------------------------------------===// + +template<typename RegionTy> struct MemRegionManagerTrait; + +template <typename RegionTy, typename A1> +RegionTy* MemRegionManager::getRegion(const A1 a1) { +   +  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = +  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); +   +  llvm::FoldingSetNodeID ID; +  RegionTy::ProfileRegion(ID, a1, superRegion); +  void* InsertPos; +  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, +                                                                   InsertPos)); +   +  if (!R) { +    R = (RegionTy*) A.Allocate<RegionTy>(); +    new (R) RegionTy(a1, superRegion); +    Regions.InsertNode(R, InsertPos); +  } +   +  return R; +} + +template <typename RegionTy, typename A1> +RegionTy* MemRegionManager::getSubRegion(const A1 a1, +                                         const MemRegion *superRegion) { +  llvm::FoldingSetNodeID ID; +  RegionTy::ProfileRegion(ID, a1, superRegion); +  void* InsertPos; +  RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, +                                                                   InsertPos)); +   +  if (!R) { +    R = (RegionTy*) A.Allocate<RegionTy>(); +    new (R) RegionTy(a1, superRegion); +    Regions.InsertNode(R, InsertPos); +  } +   +  return R; +} + +template <typename RegionTy, typename A1, typename A2> +RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) { +   +  const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = +  MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2); +   +  llvm::FoldingSetNodeID ID; +  RegionTy::ProfileRegion(ID, a1, a2, 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, superRegion); +    Regions.InsertNode(R, InsertPos); +  } +   +  return R; +} + +template <typename RegionTy, typename A1, typename A2> +RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, +                                         const MemRegion *superRegion) { +   +  llvm::FoldingSetNodeID ID; +  RegionTy::ProfileRegion(ID, a1, a2, 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, superRegion); +    Regions.InsertNode(R, InsertPos); +  } +   +  return R; +} + +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.  //===----------------------------------------------------------------------===// @@ -61,10 +165,24 @@ MemRegionManager* SubRegion::getMemRegionManager() const {    } while (1);  } +const StackFrameContext *VarRegion::getStackFrame() const { +  const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace()); +  return SSR ? SSR->getStackFrame() : NULL; +} + +//===----------------------------------------------------------------------===// +// FoldingSet profiling. +//===----------------------------------------------------------------------===// +  void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {    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) { @@ -109,7 +227,7 @@ void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {  }  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, @@ -148,27 +266,29 @@ void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {  }  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());  }  //===----------------------------------------------------------------------===// @@ -249,36 +369,58 @@ void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {  // MemRegionManager methods.  //===----------------------------------------------------------------------===// -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;  } -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;  } -MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() { -  return LazyAllocate(stackArguments); +const StackLocalsSpaceRegion* +MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { +  assert(STC); +  if (STC == cachedStackLocalsFrame) +    return cachedStackLocalsRegion; +  cachedStackLocalsFrame = STC; +  return LazyAllocate(cachedStackLocalsRegion, STC);  } -MemSpaceRegion* MemRegionManager::getGlobalsRegion() { +const StackArgumentsSpaceRegion * +MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { +  assert(STC); +  if (STC == cachedStackArgumentsFrame) +    return cachedStackArgumentsRegion; +   +  cachedStackArgumentsFrame = STC; +  return LazyAllocate(cachedStackArgumentsRegion, STC); +} + +const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {    return LazyAllocate(globals);  } -MemSpaceRegion* MemRegionManager::getHeapRegion() { +const HeapSpaceRegion *MemRegionManager::getHeapRegion() {    return LazyAllocate(heap);  } -MemSpaceRegion* MemRegionManager::getUnknownRegion() { +const MemSpaceRegion *MemRegionManager::getUnknownRegion() {    return LazyAllocate(unknown);  } -MemSpaceRegion* MemRegionManager::getCodeRegion() { +const MemSpaceRegion *MemRegionManager::getCodeRegion() {    return LazyAllocate(code);  } @@ -286,40 +428,79 @@ MemSpaceRegion* MemRegionManager::getCodeRegion() {  // Constructing regions.  //===----------------------------------------------------------------------===// -StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) { -  return getRegion<StringRegion>(Str); +const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) { +  return getSubRegion<StringRegion>(Str, getGlobalsRegion());  } -VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, -                                          const LocationContext *LC) { +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 DeclContext *DC = D->getDeclContext(); +    const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC); -  return getRegion<VarRegion>(D, LC); +    if (!STC) +      sReg = getUnknownRegion(); +    else { +      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);  } -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 VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, +                                                const MemRegion *superR) { +  return getSubRegion<VarRegion>(D, superR); +} + +const BlockDataRegion * +MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, +                                     const LocationContext *LC) { +  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);  } -CompoundLiteralRegion* -MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) { -  return getRegion<CompoundLiteralRegion>(CL); +const CompoundLiteralRegion* +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);  } -ElementRegion* +const ElementRegion*  MemRegionManager::getElementRegion(QualType elementType, SVal Idx,                                     const MemRegion* superRegion,                                     ASTContext& Ctx){ @@ -342,41 +523,47 @@ MemRegionManager::getElementRegion(QualType elementType, SVal Idx,    return R;  } -FunctionTextRegion * +const FunctionTextRegion *  MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) { -  return getRegion<FunctionTextRegion>(FD); +  return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());  } -BlockTextRegion *MemRegionManager::getBlockTextRegion(const BlockDecl *BD, -                                                      CanQualType locTy) { -  return getRegion<BlockTextRegion>(BD, locTy); +const BlockTextRegion * +MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, +                                     AnalysisContext *AC) { +  return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());  }  /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. -SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) { -  return getRegion<SymbolicRegion>(sym); +const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { +  return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());  } -FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d, -                                              const MemRegion* superRegion) { +const FieldRegion * +MemRegionManager::getFieldRegion(const FieldDecl* d, +                                 const MemRegion* superRegion){    return getSubRegion<FieldRegion>(d, superRegion);  } -ObjCIvarRegion* +const ObjCIvarRegion*  MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,                                      const MemRegion* superRegion) {    return getSubRegion<ObjCIvarRegion>(d, superRegion);  } -ObjCObjectRegion* +const ObjCObjectRegion*  MemRegionManager::getObjCObjectRegion(const ObjCInterfaceDecl* d,                                        const MemRegion* superRegion) {    return getSubRegion<ObjCObjectRegion>(d, superRegion);  } -AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) { -  return getRegion<AllocaRegion>(E, cnt); +const AllocaRegion* +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 { @@ -392,52 +579,30 @@ const MemSpaceRegion *MemRegion::getMemorySpace() const {  }  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 @@ -543,7 +708,7 @@ void BlockDataRegion::LazyInitializeReferencedVars() {    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()); @@ -558,10 +723,25 @@ void BlockDataRegion::LazyInitializeReferencedVars() {    typedef BumpVector<const MemRegion*> VarVec;    VarVec *BV = (VarVec*) A.Allocate<VarVec>(); -  new (BV) VarVec(BC, (E - I) / sizeof(*I)); +  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;  } @@ -573,7 +753,8 @@ BlockDataRegion::referenced_vars_begin() const {    BumpVector<const MemRegion*> *Vec =      static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); -  return Vec == (void*) 0x1 ? NULL : Vec->begin();   +  return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ? +                                                   NULL : Vec->begin());  }  BlockDataRegion::referenced_vars_iterator @@ -583,5 +764,6 @@ BlockDataRegion::referenced_vars_end() const {    BumpVector<const MemRegion*> *Vec =      static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); -  return Vec == (void*) 0x1 ? NULL : Vec->end();   +  return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ? +                                                   NULL : Vec->end());  }  | 
