diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-12-13 19:24:37 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-12-13 19:24:37 +0000 |
commit | abb042f33ea8e6107a7dc8efc51d2ace329f9f48 (patch) | |
tree | a90ad7bccfa3c5604d02c40af6754b619d066511 /lib | |
parent | 71e38c48609b3502d24a47d39a21f1e73402a0e1 (diff) |
A series of cleanups/fixes motivated by <rdar://problem/6442306>:
GRExprEngine (VisitCast):
- When using StoreManager::CastRegion, always use the state and value it returns to generate the next node. Failure to do so means that region values returned that don't require the state to be modified will get ignored.
MemRegion:
- Tighten the interface for ElementRegion. Now ElementRegion can only be created with a super region that is a 'TypedRegion' instead of any MemRegion. Code in BasicStoreManager/RegionStoreManager already assumed this, but it would result in a dynamic assertion check (and crash) rather than just having the compiler forbid the construction of such regions.
- Added ElementRegion::getArrayRegion() to return the 'typed version' of an ElementRegion's super region.
- Removed bogus assertion in ElementRegion::getType() that assumed that the super region was an AnonTypedRegion. All that matters is that it is a TypedRegion, which is now true all the time by design.
BasicStore:
- Modified getLValueElement() to check if the 'array' region is a TypedRegion before creating an ElementRegion. This conforms to the updated interface for ElementRegion.
RegionStore:
- In ArrayToPointer() gracefully handle things we don't reason about, and only create an ElementRegion if the array region is indeed a TypedRegion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60990 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 23 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 12 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 16 |
4 files changed, 37 insertions, 22 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 207f609609..91d85c4c2b 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -171,7 +171,7 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, return Base; Loc BaseL = cast<Loc>(Base); - const MemRegion* BaseR = 0; + const TypedRegion* BaseR = 0; switch(BaseL.getSubKind()) { case loc::SymbolValKind: { @@ -194,9 +194,19 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, // Technically we can get here if people do funny things with casts. return UndefinedVal(); - case loc::MemRegionKind: - BaseR = cast<loc::MemRegionVal>(BaseL).getRegion(); + case loc::MemRegionKind: { + const MemRegion *R = cast<loc::MemRegionVal>(BaseL).getRegion(); + if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { + BaseR = TR; + break; + } + + // FIXME: Handle SymbolRegions? Shouldn't be possible in + // BasicStoreManager. + assert(!isa<SymbolicRegion>(R)); + break; + } case loc::ConcreteIntKind: // While these seem funny, this can happen through casts. @@ -210,9 +220,10 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, return Base; } - // We return an "unknown" index because we aren't reasoning about indices - // at all. - return loc::MemRegionVal(MRMgr.getElementRegion(UnknownVal(), BaseR)); + if (BaseR) + return loc::MemRegionVal(MRMgr.getElementRegion(UnknownVal(), BaseR)); + else + return UnknownVal(); } SVal BasicStoreManager::Retrieve(const GRState* state, Loc LV, QualType T) { diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 96776b46ff..74e1a07631 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1731,7 +1731,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ continue; } - // Check for casts from AllocaRegion pointer to typed pointer. + // Check for casts from a pointer to a region to typed pointer. if (isa<loc::MemRegionVal>(V)) { assert(Loc::IsLocType(T)); assert(Loc::IsLocType(ExTy)); @@ -1740,14 +1740,8 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){ std::pair<const GRState*, SVal> Res = getStoreManager().CastRegion(St, V, T, CastE); - const GRState* NewSt = Res.first; - SVal NewPtr = Res.second; - - // If no new region is created, fall through to the default case. - if (NewSt != St) { - MakeNode(Dst, CastE, N, BindExpr(NewSt, CastE, NewPtr)); - continue; - } + MakeNode(Dst, CastE, N, BindExpr(Res.first, CastE, Res.second)); + continue; } // All other cases. diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 1e580a8cd3..94ffb3f152 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -107,14 +107,13 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { } QualType ElementRegion::getType(ASTContext& C) const { - QualType T = cast<TypedRegion>(superRegion)->getType(C); + QualType T = getArrayRegion()->getType(C); if (isa<ArrayType>(T.getTypePtr())) { ArrayType* AT = cast<ArrayType>(T.getTypePtr()); return AT->getElementType(); } else { - assert (isa<AnonTypedRegion>(superRegion)); PointerType* PtrT = cast<PointerType>(T.getTypePtr()); QualType PTy = PtrT->getPointeeType(); return C.getCanonicalType(PTy); @@ -278,8 +277,9 @@ MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) { return R; } -ElementRegion* MemRegionManager::getElementRegion(SVal Idx, - const MemRegion* superRegion){ +ElementRegion* +MemRegionManager::getElementRegion(SVal Idx, const TypedRegion* superRegion){ + llvm::FoldingSetNodeID ID; ElementRegion::ProfileRegion(ID, Idx, superRegion); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index e065c5c410..defa80f324 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -287,7 +287,7 @@ SVal RegionStoreManager::getLValueElement(const GRState* St, SVal NewIdx = CI1->EvalBinOp(getBasicVals(), BinaryOperator::Add, *CI2); return loc::MemRegionVal(MRMgr.getElementRegion(NewIdx, - ElemR->getSuperRegion())); + ElemR->getArrayRegion())); } return UnknownVal(); @@ -360,8 +360,18 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, // Cast 'pointer to array' to 'pointer to the first element of array'. SVal RegionStoreManager::ArrayToPointer(SVal Array) { - const MemRegion* ArrayR = cast<loc::MemRegionVal>(&Array)->getRegion(); - + if (Array.isUnknownOrUndef()) + return Array; + + if (!isa<loc::MemRegionVal>(Array)) + return UnknownVal(); + + const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion(); + const TypedRegion* ArrayR = dyn_cast<TypedRegion>(R); + + if (ArrayR) + return UnknownVal(); + nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false)); ElementRegion* ER = MRMgr.getElementRegion(Idx, ArrayR); |