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);
}