diff options
-rw-r--r-- | include/clang/Checker/PathSensitive/GRState.h | 4 | ||||
-rw-r--r-- | include/clang/Checker/PathSensitive/MemRegion.h | 8 | ||||
-rw-r--r-- | include/clang/Checker/PathSensitive/Store.h | 2 | ||||
-rw-r--r-- | lib/Checker/MemRegion.cpp | 2 | ||||
-rw-r--r-- | lib/Checker/RegionStore.cpp | 14 | ||||
-rw-r--r-- | lib/Checker/SVals.cpp | 2 | ||||
-rw-r--r-- | lib/Checker/Store.cpp | 12 | ||||
-rw-r--r-- | test/Analysis/idempotent-operations.c | 30 |
8 files changed, 55 insertions, 19 deletions
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h index ac382898d8..878f564491 100644 --- a/include/clang/Checker/PathSensitive/GRState.h +++ b/include/clang/Checker/PathSensitive/GRState.h @@ -650,7 +650,9 @@ inline SVal GRState::getLValue(const FieldDecl* D, SVal Base) const { } inline SVal GRState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{ - return getStateManager().StoreMgr->getLValueElement(ElementType, Idx, Base); + if (NonLoc *N = dyn_cast<NonLoc>(&Idx)) + return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base); + return UnknownVal(); } inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const { diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h index 96f906af28..82b0c14f20 100644 --- a/include/clang/Checker/PathSensitive/MemRegion.h +++ b/include/clang/Checker/PathSensitive/MemRegion.h @@ -788,9 +788,9 @@ class ElementRegion : public TypedRegion { friend class MemRegionManager; QualType ElementType; - SVal Index; + NonLoc Index; - ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg) + ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg) : TypedRegion(sReg, ElementRegionKind), ElementType(elementType), Index(Idx) { assert((!isa<nonloc::ConcreteInt>(&Idx) || @@ -803,7 +803,7 @@ class ElementRegion : public TypedRegion { public: - SVal getIndex() const { return Index; } + NonLoc getIndex() const { return Index; } QualType getValueType() const { return ElementType; @@ -942,7 +942,7 @@ public: /// getElementRegion - Retrieve the memory region associated with the /// associated element type, index, and super region. - const ElementRegion *getElementRegion(QualType elementType, SVal Idx, + const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, const MemRegion *superRegion, ASTContext &Ctx); diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h index a1a41847a2..1ead466136 100644 --- a/include/clang/Checker/PathSensitive/Store.h +++ b/include/clang/Checker/PathSensitive/Store.h @@ -112,7 +112,7 @@ public: return getLValueFieldOrIvar(D, Base); } - virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base); + virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base); // FIXME: This should soon be eliminated altogether; clients should deal with // region extents directly. diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp index 3f706e145a..ddcb7d2687 100644 --- a/lib/Checker/MemRegion.cpp +++ b/lib/Checker/MemRegion.cpp @@ -624,7 +624,7 @@ MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL, } const ElementRegion* -MemRegionManager::getElementRegion(QualType elementType, SVal Idx, +MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, const MemRegion* superRegion, ASTContext& Ctx){ diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 4051f4d39b..91f7cfaf6c 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -786,7 +786,7 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { ArrayType *AT = cast<ArrayType>(T); T = AT->getElementType(); - SVal ZeroIdx = ValMgr.makeZeroArrayIndex(); + NonLoc ZeroIdx = ValMgr.makeZeroArrayIndex(); return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx)); } @@ -828,14 +828,14 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, else EleTy = T->getAs<ObjCObjectPointerType>()->getPointeeType(); - SVal ZeroIdx = ValMgr.makeZeroArrayIndex(); + const NonLoc &ZeroIdx = ValMgr.makeZeroArrayIndex(); ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, Ctx); break; } case MemRegion::AllocaRegionKind: { const AllocaRegion *AR = cast<AllocaRegion>(MR); QualType EleTy = Ctx.CharTy; // Create an ElementRegion of bytes. - SVal ZeroIdx = ValMgr.makeZeroArrayIndex(); + NonLoc ZeroIdx = ValMgr.makeZeroArrayIndex(); ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, Ctx); break; } @@ -889,8 +889,12 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, SVal NewIdx = Base->evalBinOp(ValMgr, Op, cast<nonloc::ConcreteInt>(ValMgr.convertToArrayIndex(*Offset))); + + if (!isa<NonLoc>(NewIdx)) + return UnknownVal(); + const MemRegion* NewER = - MRMgr.getElementRegion(ER->getElementType(), NewIdx, + MRMgr.getElementRegion(ER->getElementType(), cast<NonLoc>(NewIdx), ER->getSuperRegion(), Ctx); return ValMgr.makeLoc(NewER); } @@ -1449,7 +1453,7 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, if (VI == VE) break; - SVal Idx = ValMgr.makeArrayIndex(i); + const NonLoc &Idx = ValMgr.makeArrayIndex(i); const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx); if (ElementTy->isStructureOrClassType()) diff --git a/lib/Checker/SVals.cpp b/lib/Checker/SVals.cpp index 97ba74e948..937b948fc9 100644 --- a/lib/Checker/SVals.cpp +++ b/lib/Checker/SVals.cpp @@ -270,7 +270,7 @@ void SVal::dump() const { dumpToStream(llvm::errs()); } void SVal::dumpToStream(llvm::raw_ostream& os) const { switch (getBaseKind()) { case UnknownKind: - os << "Invalid"; + os << "Unknown"; break; case NonLocKind: cast<NonLoc>(this)->dumpToStream(os); diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp index 1cb5cd70ca..aaa518edc8 100644 --- a/lib/Checker/Store.cpp +++ b/lib/Checker/Store.cpp @@ -28,7 +28,7 @@ Store StoreManager::EnterStackFrame(const GRState *state, const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, QualType EleTy, uint64_t index) { - SVal idx = ValMgr.makeArrayIndex(index); + NonLoc idx = ValMgr.makeArrayIndex(index); return MRMgr.getElementRegion(EleTy, idx, Base, ValMgr.getContext()); } @@ -45,7 +45,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, QualType T) { - SVal idx = ValMgr.makeZeroArrayIndex(); + NonLoc idx = ValMgr.makeZeroArrayIndex(); assert(!T.isNull()); return MRMgr.getElementRegion(T, idx, R, Ctx); } @@ -267,7 +267,7 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl* D, SVal Base) { return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR)); } -SVal StoreManager::getLValueElement(QualType elementType, SVal Offset, +SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, SVal Base) { // If the base is an unknown or undefined value, just return it back. @@ -283,7 +283,7 @@ SVal StoreManager::getLValueElement(QualType elementType, SVal Offset, const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion); // Convert the offset to the appropriate size and signedness. - Offset = ValMgr.convertToArrayIndex(Offset); + Offset = cast<NonLoc>(ValMgr.convertToArrayIndex(Offset)); if (!ElemR) { // @@ -322,8 +322,8 @@ SVal StoreManager::getLValueElement(QualType elementType, SVal Offset, assert(BaseIdxI.isSigned()); // Compute the new index. - SVal NewIdx = nonloc::ConcreteInt( - ValMgr.getBasicValueFactory().getValue(BaseIdxI + OffI)); + nonloc::ConcreteInt NewIdx(ValMgr.getBasicValueFactory().getValue(BaseIdxI + + OffI)); // Construct the new ElementRegion. const MemRegion *ArrayR = ElemR->getSuperRegion(); diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c index d88bf49485..c673f0062f 100644 --- a/test/Analysis/idempotent-operations.c +++ b/test/Analysis/idempotent-operations.c @@ -194,3 +194,33 @@ void false8() { a = (short)a; // no-warning test(a); } + +// This test case previously flagged a warning at 'b == c' because the +// analyzer previously allowed 'UnknownVal' as the index for ElementRegions. +typedef struct RDar8431728_F { + int RDar8431728_A; + unsigned char *RDar8431728_B; + int RDar8431728_E[6]; +} RDar8431728_D; +static inline int RDar8431728_C(RDar8431728_D * s, int n, + unsigned char **RDar8431728_B_ptr) { + int xy, wrap, pred, a, b, c; + + xy = s->RDar8431728_E[n]; + wrap = s->RDar8431728_A; + + a = s->RDar8431728_B[xy - 1]; + b = s->RDar8431728_B[xy - 1 - wrap]; + c = s->RDar8431728_B[xy - wrap]; + + if (b == c) { // no-warning + pred = a; + } else { + pred = c; + } + + *RDar8431728_B_ptr = &s->RDar8431728_B[xy]; + + return pred; +} + |