Replace SVal llvm::cast support to be well-defined.

See r175462 for another example/more details.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175594 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2013-02-20 05:52:05 +00:00
Родитель a905c4fd25
Коммит 5251abea41
44 изменённых файлов: 579 добавлений и 505 удалений

Просмотреть файл

@ -429,11 +429,11 @@ public:
geteagerlyAssumeBinOpBifurcationTags();
SVal evalMinus(SVal X) {
return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
return X.isValid() ? svalBuilder.evalMinus(X.castAs<NonLoc>()) : X;
}
SVal evalComplement(SVal X) {
return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
return X.isValid() ? svalBuilder.evalComplement(X.castAs<NonLoc>()) : X;
}
public:
@ -445,7 +445,8 @@ public:
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
NonLoc L, SVal R, QualType T) {
return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
return R.isValid() ? svalBuilder.evalBinOpNN(state, op, L,
R.castAs<NonLoc>(), T) : R;
}
SVal evalBinOp(ProgramStateRef ST, BinaryOperator::Opcode Op,

Просмотреть файл

@ -991,8 +991,8 @@ class ElementRegion : public TypedValueRegion {
ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
: TypedValueRegion(sReg, ElementRegionKind),
ElementType(elementType), Index(Idx) {
assert((!isa<nonloc::ConcreteInt>(&Idx) ||
cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) &&
assert((!Idx.getAs<nonloc::ConcreteInt>() ||
Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
"The index must be signed");
}

Просмотреть файл

@ -620,22 +620,24 @@ inline ProgramStateRef ProgramState::assume(DefinedOrUnknownSVal Cond,
bool Assumption) const {
if (Cond.isUnknown())
return this;
return getStateManager().ConstraintMgr->assume(this, cast<DefinedSVal>(Cond),
Assumption);
return getStateManager().ConstraintMgr
->assume(this, Cond.castAs<DefinedSVal>(), Assumption);
}
inline std::pair<ProgramStateRef , ProgramStateRef >
ProgramState::assume(DefinedOrUnknownSVal Cond) const {
if (Cond.isUnknown())
return std::make_pair(this, this);
return getStateManager().ConstraintMgr->assumeDual(this,
cast<DefinedSVal>(Cond));
return getStateManager().ConstraintMgr
->assumeDual(this, Cond.castAs<DefinedSVal>());
}
inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
return !isa<Loc>(LV) ? this : bindLoc(cast<Loc>(LV), V);
if (llvm::Optional<Loc> L = LV.getAs<Loc>())
return bindLoc(*L, V);
return this;
}
inline Loc ProgramState::getLValue(const VarDecl *VD,
@ -669,7 +671,7 @@ inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
}
inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
if (llvm::Optional<NonLoc> N = Idx.getAs<NonLoc>())
return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
return UnknownVal();
}

Просмотреть файл

@ -69,6 +69,25 @@ protected:
public:
explicit SVal() : Data(0), Kind(0) {}
template<typename T>
T castAs() const {
assert(T::isType(*this));
T t;
SVal& sv = t;
sv = *this;
return t;
}
template<typename T>
llvm::Optional<T> getAs() const {
if (!T::isType(*this))
return llvm::Optional<T>();
T t;
SVal& sv = t;
sv = *this;
return t;
}
/// BufferTy - A temporary buffer to hold a set of SVals.
typedef SmallVector<SVal,5> BufferTy;
@ -161,8 +180,10 @@ class UndefinedVal : public SVal {
public:
UndefinedVal() : SVal(UndefinedKind) {}
static inline bool classof(const SVal* V) {
return V->getBaseKind() == UndefinedKind;
private:
friend class SVal;
static bool isType(const SVal& V) {
return V.getBaseKind() == UndefinedKind;
}
};
@ -174,16 +195,17 @@ private:
bool isValid() const LLVM_DELETED_FUNCTION;
protected:
DefinedOrUnknownSVal() {}
explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
: SVal(d, isLoc, ValKind) {}
explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
: SVal(k, D) {}
public:
// Implement isa<T> support.
static inline bool classof(const SVal *V) {
return !V->isUndef();
private:
friend class SVal;
static bool isType(const SVal& V) {
return !V.isUndef();
}
};
@ -191,8 +213,10 @@ class UnknownVal : public DefinedOrUnknownSVal {
public:
explicit UnknownVal() : DefinedOrUnknownSVal(UnknownKind) {}
static inline bool classof(const SVal *V) {
return V->getBaseKind() == UnknownKind;
private:
friend class SVal;
static bool isType(const SVal& V) {
return V.getBaseKind() == UnknownKind;
}
};
@ -204,46 +228,51 @@ private:
bool isUnknownOrUndef() const LLVM_DELETED_FUNCTION;
bool isValid() const LLVM_DELETED_FUNCTION;
protected:
DefinedSVal() {}
explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind)
: DefinedOrUnknownSVal(d, isLoc, ValKind) {}
public:
// Implement isa<T> support.
static inline bool classof(const SVal *V) {
return !V->isUnknownOrUndef();
private:
friend class SVal;
static bool isType(const SVal& V) {
return !V.isUnknownOrUndef();
}
};
class NonLoc : public DefinedSVal {
protected:
NonLoc() {}
explicit NonLoc(unsigned SubKind, const void *d)
: DefinedSVal(d, false, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind;
private:
friend class SVal;
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind;
}
};
class Loc : public DefinedSVal {
protected:
Loc() {}
explicit Loc(unsigned SubKind, const void *D)
: DefinedSVal(const_cast<void*>(D), true, SubKind) {}
public:
void dumpToStream(raw_ostream &Out) const;
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind;
}
static inline bool isLocType(QualType T) {
return T->isAnyPointerType() || T->isBlockPointerType() ||
T->isReferenceType();
}
private:
friend class SVal;
static bool isType(const SVal& V) {
return V.getBaseKind() == LocKind;
}
};
//==------------------------------------------------------------------------==//
@ -264,17 +293,20 @@ public:
return (const SymExpr*) Data;
}
bool isExpression() {
bool isExpression() const {
return !isa<SymbolData>(getSymbol());
}
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == SymbolValKind;
private:
friend class SVal;
SymbolVal() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == SymbolValKind;
}
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == SymbolValKind;
static bool isType(const NonLoc& V) {
return V.getSubKind() == SymbolValKind;
}
};
@ -295,38 +327,40 @@ public:
ConcreteInt evalMinus(SValBuilder &svalBuilder) const;
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == ConcreteIntKind;
private:
friend class SVal;
ConcreteInt() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == ConcreteIntKind;
}
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == ConcreteIntKind;
static bool isType(const NonLoc& V) {
return V.getSubKind() == ConcreteIntKind;
}
};
class LocAsInteger : public NonLoc {
friend class ento::SValBuilder;
explicit LocAsInteger(const std::pair<SVal, uintptr_t>& data) :
NonLoc(LocAsIntegerKind, &data) {
assert (isa<Loc>(data.first));
}
explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
: NonLoc(LocAsIntegerKind, &data) {
assert (data.first.getAs<Loc>());
}
public:
Loc getLoc() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
return cast<Loc>(D->first);
return D->first.castAs<Loc>();
}
const Loc& getPersistentLoc() const {
Loc getPersistentLoc() const {
const std::pair<SVal, uintptr_t> *D =
static_cast<const std::pair<SVal, uintptr_t> *>(Data);
const SVal& V = D->first;
return cast<Loc>(V);
return V.castAs<Loc>();
}
unsigned getNumBits() const {
@ -335,14 +369,16 @@ public:
return D->second;
}
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == LocAsIntegerKind;
private:
friend class SVal;
LocAsInteger() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == LocAsIntegerKind;
}
static inline bool classof(const NonLoc* V) {
return V->getSubKind() == LocAsIntegerKind;
static bool isType(const NonLoc& V) {
return V.getSubKind() == LocAsIntegerKind;
}
};
@ -360,12 +396,15 @@ public:
iterator begin() const;
iterator end() const;
static bool classof(const SVal* V) {
return V->getBaseKind() == NonLocKind && V->getSubKind() == CompoundValKind;
private:
friend class SVal;
CompoundVal() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind && V.getSubKind() == CompoundValKind;
}
static bool classof(const NonLoc* V) {
return V->getSubKind() == CompoundValKind;
static bool isType(const NonLoc& V) {
return V.getSubKind() == CompoundValKind;
}
};
@ -381,12 +420,15 @@ public:
const void *getStore() const;
const TypedValueRegion *getRegion() const;
static bool classof(const SVal *V) {
return V->getBaseKind() == NonLocKind &&
V->getSubKind() == LazyCompoundValKind;
private:
friend class SVal;
LazyCompoundVal() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == NonLocKind &&
V.getSubKind() == LazyCompoundValKind;
}
static bool classof(const NonLoc *V) {
return V->getSubKind() == LazyCompoundValKind;
static bool isType(const NonLoc& V) {
return V.getSubKind() == LazyCompoundValKind;
}
};
@ -408,12 +450,15 @@ public:
return static_cast<const LabelDecl*>(Data);
}
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind && V->getSubKind() == GotoLabelKind;
private:
friend class SVal;
GotoLabel() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == LocKind && V.getSubKind() == GotoLabelKind;
}
static inline bool classof(const Loc* V) {
return V->getSubKind() == GotoLabelKind;
static bool isType(const Loc& V) {
return V.getSubKind() == GotoLabelKind;
}
};
@ -443,14 +488,16 @@ public:
return getRegion() != R.getRegion();
}
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == MemRegionKind;
private:
friend class SVal;
MemRegionVal() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == LocKind &&
V.getSubKind() == MemRegionKind;
}
static inline bool classof(const Loc* V) {
return V->getSubKind() == MemRegionKind;
static bool isType(const Loc& V) {
return V.getSubKind() == MemRegionKind;
}
};
@ -466,14 +513,16 @@ public:
SVal evalBinOp(BasicValueFactory& BasicVals, BinaryOperator::Opcode Op,
const ConcreteInt& R) const;
// Implement isa<T> support.
static inline bool classof(const SVal* V) {
return V->getBaseKind() == LocKind &&
V->getSubKind() == ConcreteIntKind;
private:
friend class SVal;
ConcreteInt() {}
static bool isType(const SVal& V) {
return V.getBaseKind() == LocKind &&
V.getSubKind() == ConcreteIntKind;
}
static inline bool classof(const Loc* V) {
return V->getSubKind() == ConcreteIntKind;
static bool isType(const Loc& V) {
return V.getSubKind() == ConcreteIntKind;
}
};

Просмотреть файл

@ -53,7 +53,7 @@ public:
RegionRawOffsetV2(const SubRegion* base, SVal offset)
: baseRegion(base), byteOffset(offset) {}
NonLoc getByteOffset() const { return cast<NonLoc>(byteOffset); }
NonLoc getByteOffset() const { return byteOffset.castAs<NonLoc>(); }
const SubRegion *getRegion() const { return baseRegion; }
static RegionRawOffsetV2 computeOffset(ProgramStateRef state,
@ -110,13 +110,12 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
SVal extentBegin = computeExtentBegin(svalBuilder, rawOffset.getRegion());
if (isa<NonLoc>(extentBegin)) {
SVal lowerBound
= svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(),
cast<NonLoc>(extentBegin),
if (llvm::Optional<NonLoc> NV = extentBegin.getAs<NonLoc>()) {
SVal lowerBound =
svalBuilder.evalBinOpNN(state, BO_LT, rawOffset.getByteOffset(), *NV,
svalBuilder.getConditionType());
NonLoc *lowerBoundToCheck = dyn_cast<NonLoc>(&lowerBound);
llvm::Optional<NonLoc> lowerBoundToCheck = lowerBound.getAs<NonLoc>();
if (!lowerBoundToCheck)
return;
@ -140,15 +139,15 @@ void ArrayBoundCheckerV2::checkLocation(SVal location, bool isLoad,
// we are doing a load/store after the last valid offset.
DefinedOrUnknownSVal extentVal =
rawOffset.getRegion()->getExtent(svalBuilder);
if (!isa<NonLoc>(extentVal))
if (!extentVal.getAs<NonLoc>())
break;
SVal upperbound
= svalBuilder.evalBinOpNN(state, BO_GE, rawOffset.getByteOffset(),
cast<NonLoc>(extentVal),
extentVal.castAs<NonLoc>(),
svalBuilder.getConditionType());
NonLoc *upperboundToCheck = dyn_cast<NonLoc>(&upperbound);
llvm::Optional<NonLoc> upperboundToCheck = upperbound.getAs<NonLoc>();
if (!upperboundToCheck)
break;
@ -235,7 +234,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
// is unknown or undefined, we lazily substitute '0'. Otherwise,
// return 'val'.
static inline SVal getValue(SVal val, SValBuilder &svalBuilder) {
return isa<UndefinedVal>(val) ? svalBuilder.makeArrayIndex(0) : val;
return val.getAs<UndefinedVal>() ? svalBuilder.makeArrayIndex(0) : val;
}
// Scale a base value by a scaling factor, and return the scaled
@ -256,9 +255,9 @@ static SVal addValue(ProgramStateRef state, SVal x, SVal y,
// only care about computing offsets.
if (x.isUnknownOrUndef() || y.isUnknownOrUndef())
return UnknownVal();
return svalBuilder.evalBinOpNN(state, BO_Add,
cast<NonLoc>(x), cast<NonLoc>(y),
return svalBuilder.evalBinOpNN(state, BO_Add, x.castAs<NonLoc>(),
y.castAs<NonLoc>(),
svalBuilder.getArrayIndexType());
}
@ -284,7 +283,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
case MemRegion::ElementRegionKind: {
const ElementRegion *elemReg = cast<ElementRegion>(region);
SVal index = elemReg->getIndex();
if (!isa<NonLoc>(index))
if (!index.getAs<NonLoc>())
return RegionRawOffsetV2();
QualType elemType = elemReg->getElementType();
// If the element is an incomplete type, go no further.
@ -296,7 +295,7 @@ RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state,
offset = addValue(state,
getValue(offset, svalBuilder),
scaleValue(state,
cast<NonLoc>(index),
index.castAs<NonLoc>(),
astContext.getTypeSizeInChars(elemType),
svalBuilder),
svalBuilder);

Просмотреть файл

@ -51,13 +51,13 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
continue;
SVal V = Call.getArgSVal(idx);
DefinedSVal *DV = dyn_cast<DefinedSVal>(&V);
llvm::Optional<DefinedSVal> DV = V.getAs<DefinedSVal>();
// If the value is unknown or undefined, we can't perform this check.
if (!DV)
continue;
if (!isa<Loc>(*DV)) {
if (!DV->getAs<Loc>()) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
const Expr *ArgE = Call.getArgExpr(idx);
@ -69,11 +69,12 @@ void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
if (nonloc::CompoundVal *CSV = dyn_cast<nonloc::CompoundVal>(DV)) {
if (llvm::Optional<nonloc::CompoundVal> CSV =
DV->getAs<nonloc::CompoundVal>()) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
V = *CSV_I;
DV = dyn_cast<DefinedSVal>(&V);
DV = V.getAs<DefinedSVal>();
assert(++CSV_I == CSV->end());
if (!DV)
continue;

Просмотреть файл

@ -84,7 +84,7 @@ static FoundationClass findKnownClass(const ObjCInterfaceDecl *ID) {
}
static inline bool isNil(SVal X) {
return isa<loc::ConcreteInt>(X);
return X.getAs<loc::ConcreteInt>();
}
//===----------------------------------------------------------------------===//
@ -290,7 +290,8 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
llvm::Optional<nonloc::ConcreteInt> V =
TheTypeVal.getAs<nonloc::ConcreteInt>();
if (!V)
return;
@ -308,7 +309,8 @@ void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
llvm::Optional<loc::MemRegionVal> LV =
TheValueExpr.getAs<loc::MemRegionVal>();
if (!LV)
return;
@ -409,13 +411,14 @@ void CFRetainReleaseChecker::checkPreStmt(const CallExpr *CE,
// Get the argument's value.
const Expr *Arg = CE->getArg(0);
SVal ArgVal = state->getSVal(Arg, C.getLocationContext());
DefinedSVal *DefArgVal = dyn_cast<DefinedSVal>(&ArgVal);
llvm::Optional<DefinedSVal> DefArgVal = ArgVal.getAs<DefinedSVal>();
if (!DefArgVal)
return;
// Get a NULL value.
SValBuilder &svalBuilder = C.getSValBuilder();
DefinedSVal zero = cast<DefinedSVal>(svalBuilder.makeZeroVal(Arg->getType()));
DefinedSVal zero =
svalBuilder.makeZeroVal(Arg->getType()).castAs<DefinedSVal>();
// Make an expression asserting that they're equal.
DefinedOrUnknownSVal ArgIsNull = svalBuilder.evalEQ(state, zero, *DefArgVal);
@ -619,7 +622,7 @@ void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
continue;
// Ignore pointer constants.
if (isa<loc::ConcreteInt>(msg.getArgSVal(I)))
if (msg.getArgSVal(I).getAs<loc::ConcreteInt>())
continue;
// Ignore pointer types annotated with 'NSObject' attribute.
@ -716,12 +719,12 @@ void ObjCLoopChecker::checkPostStmt(const ObjCForCollectionStmt *FCS,
ElementVar = State->getSVal(Element, C.getLocationContext());
}
if (!isa<Loc>(ElementVar))
if (!ElementVar.getAs<Loc>())
return;
// Go ahead and assume the value is non-nil.
SVal Val = State->getSVal(cast<Loc>(ElementVar));
State = State->assume(cast<DefinedOrUnknownSVal>(Val), true);
SVal Val = State->getSVal(ElementVar.castAs<Loc>());
State = State->assume(Val.castAs<DefinedOrUnknownSVal>(), true);
C.addTransition(State);
}
@ -745,7 +748,8 @@ static ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
ProgramStateRef State,
CheckerContext &C) {
SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
if (DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&Val))
if (llvm::Optional<DefinedOrUnknownSVal> DV =
Val.getAs<DefinedOrUnknownSVal>())
return State->assume(*DV, true);
return State;
}

Просмотреть файл

@ -69,7 +69,7 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
// Get the value of the right-hand side. We only care about values
// that are defined (UnknownVals and UndefinedVals are handled by other
// checkers).
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&val);
llvm::Optional<DefinedSVal> DV = val.getAs<DefinedSVal>();
if (!DV)
return;
@ -85,10 +85,10 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
SVal greaterThanOrEqualToZeroVal =
svalBuilder.evalBinOp(state, BO_GE, *DV, zeroVal,
svalBuilder.getConditionType());
DefinedSVal *greaterThanEqualToZero =
dyn_cast<DefinedSVal>(&greaterThanOrEqualToZeroVal);
llvm::Optional<DefinedSVal> greaterThanEqualToZero =
greaterThanOrEqualToZeroVal.getAs<DefinedSVal>();
if (!greaterThanEqualToZero) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.
@ -121,10 +121,10 @@ void BoolAssignmentChecker::checkBind(SVal loc, SVal val, const Stmt *S,
SVal lessThanEqToOneVal =
svalBuilder.evalBinOp(state, BO_LE, *DV, OneVal,
svalBuilder.getConditionType());
DefinedSVal *lessThanEqToOne =
dyn_cast<DefinedSVal>(&lessThanEqToOneVal);
llvm::Optional<DefinedSVal> lessThanEqToOne =
lessThanEqToOneVal.getAs<DefinedSVal>();
if (!lessThanEqToOne) {
// The SValBuilder cannot construct a valid SVal for this condition.
// This means we cannot properly reason about it.

Просмотреть файл

@ -61,7 +61,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
// SVal of the argument directly. If we save the extent in bits, we
// cannot represent values like symbol*8.
DefinedOrUnknownSVal Size =
cast<DefinedOrUnknownSVal>(state->getSVal(*(CE->arg_begin()), LCtx));
state->getSVal(*(CE->arg_begin()), LCtx).castAs<DefinedOrUnknownSVal>();
SValBuilder& svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);

Просмотреть файл

@ -201,7 +201,7 @@ REGISTER_MAP_WITH_PROGRAMSTATE(CStringLength, const MemRegion *, SVal)
std::pair<ProgramStateRef , ProgramStateRef >
CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V,
QualType Ty) {
DefinedSVal *val = dyn_cast<DefinedSVal>(&V);
llvm::Optional<DefinedSVal> val = V.getAs<DefinedSVal>();
if (!val)
return std::pair<ProgramStateRef , ProgramStateRef >(state, state);
@ -278,7 +278,7 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
SValBuilder &svalBuilder = C.getSValBuilder();
SVal Extent =
svalBuilder.convertToArrayIndex(superReg->getExtent(svalBuilder));
DefinedOrUnknownSVal Size = cast<DefinedOrUnknownSVal>(Extent);
DefinedOrUnknownSVal Size = Extent.castAs<DefinedOrUnknownSVal>();
// Get the index of the accessed element.
DefinedOrUnknownSVal Idx = cast<DefinedOrUnknownSVal>(ER->getIndex());
@ -359,18 +359,18 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
// FIXME: This assumes the caller has already checked that the access length
// is positive. And that it's unsigned.
SVal LengthVal = state->getSVal(Size, LCtx);
NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
llvm::Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
if (!Length)
return state;
// Compute the offset of the last element to be accessed: size-1.
NonLoc One = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
NonLoc LastOffset = cast<NonLoc>(svalBuilder.evalBinOpNN(state, BO_Sub,
*Length, One, sizeTy));
NonLoc One = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
NonLoc LastOffset = svalBuilder
.evalBinOpNN(state, BO_Sub, *Length, One, sizeTy).castAs<NonLoc>();
// Check that the first buffer is sufficiently long.
SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
if (llvm::Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
const Expr *warningExpr = (WarnAboutSize ? Size : FirstBuf);
SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
@ -390,7 +390,7 @@ ProgramStateRef CStringChecker::CheckBufferAccess(CheckerContext &C,
return NULL;
BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
if (Loc *BufLoc = dyn_cast<Loc>(&BufStart)) {
if (llvm::Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
const Expr *warningExpr = (WarnAboutSize ? Size : SecondBuf);
SVal BufEnd = svalBuilder.evalBinOpLN(state, BO_Add, *BufLoc,
@ -426,11 +426,11 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
SVal firstVal = state->getSVal(First, LCtx);
SVal secondVal = state->getSVal(Second, LCtx);
Loc *firstLoc = dyn_cast<Loc>(&firstVal);
llvm::Optional<Loc> firstLoc = firstVal.getAs<Loc>();
if (!firstLoc)
return state;
Loc *secondLoc = dyn_cast<Loc>(&secondVal);
llvm::Optional<Loc> secondLoc = secondVal.getAs<Loc>();
if (!secondLoc)
return state;
@ -453,7 +453,8 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
QualType cmpTy = svalBuilder.getConditionType();
SVal reverse = svalBuilder.evalBinOpLL(state, BO_GT,
*firstLoc, *secondLoc, cmpTy);
DefinedOrUnknownSVal *reverseTest = dyn_cast<DefinedOrUnknownSVal>(&reverse);
llvm::Optional<DefinedOrUnknownSVal> reverseTest =
reverse.getAs<DefinedOrUnknownSVal>();
if (!reverseTest)
return state;
@ -464,20 +465,16 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
return state;
} else {
// Switch the values so that firstVal is before secondVal.
Loc *tmpLoc = firstLoc;
firstLoc = secondLoc;
secondLoc = tmpLoc;
std::swap(firstLoc, secondLoc);
// Switch the Exprs as well, so that they still correspond.
const Expr *tmpExpr = First;
First = Second;
Second = tmpExpr;
std::swap(First, Second);
}
}
// Get the length, and make sure it too is known.
SVal LengthVal = state->getSVal(Size, LCtx);
NonLoc *Length = dyn_cast<NonLoc>(&LengthVal);
llvm::Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
if (!Length)
return state;
@ -487,21 +484,22 @@ ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
SVal FirstStart = svalBuilder.evalCast(*firstLoc, CharPtrTy,
First->getType());
Loc *FirstStartLoc = dyn_cast<Loc>(&FirstStart);
llvm::Optional<Loc> FirstStartLoc = FirstStart.getAs<Loc>();
if (!FirstStartLoc)
return state;
// Compute the end of the first buffer. Bail out if THAT fails.
SVal FirstEnd = svalBuilder.evalBinOpLN(state, BO_Add,
*FirstStartLoc, *Length, CharPtrTy);
Loc *FirstEndLoc = dyn_cast<Loc>(&FirstEnd);
llvm::Optional<Loc> FirstEndLoc = FirstEnd.getAs<Loc>();
if (!FirstEndLoc)
return state;
// Is the end of the first buffer past the start of the second buffer?
SVal Overlap = svalBuilder.evalBinOpLL(state, BO_GT,
*FirstEndLoc, *secondLoc, cmpTy);
DefinedOrUnknownSVal *OverlapTest = dyn_cast<DefinedOrUnknownSVal>(&Overlap);
llvm::Optional<DefinedOrUnknownSVal> OverlapTest =
Overlap.getAs<DefinedOrUnknownSVal>();
if (!OverlapTest)
return state;
@ -557,7 +555,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
NonLoc maxVal = svalBuilder.makeIntVal(maxValInt);
SVal maxMinusRight;
if (isa<nonloc::ConcreteInt>(right)) {
if (right.getAs<nonloc::ConcreteInt>()) {
maxMinusRight = svalBuilder.evalBinOpNN(state, BO_Sub, maxVal, right,
sizeTy);
} else {
@ -568,7 +566,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
left = right;
}
if (NonLoc *maxMinusRightNL = dyn_cast<NonLoc>(&maxMinusRight)) {
if (llvm::Optional<NonLoc> maxMinusRightNL = maxMinusRight.getAs<NonLoc>()) {
QualType cmpTy = svalBuilder.getConditionType();
// If left > max - right, we have an overflow.
SVal willOverflow = svalBuilder.evalBinOpNN(state, BO_GT, left,
@ -576,7 +574,7 @@ ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
ProgramStateRef stateOverflow, stateOkay;
llvm::tie(stateOverflow, stateOkay) =
state->assume(cast<DefinedOrUnknownSVal>(willOverflow));
state->assume(willOverflow.castAs<DefinedOrUnknownSVal>());
if (stateOverflow && !stateOkay) {
// We have an overflow. Emit a bug report.
@ -683,7 +681,7 @@ SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
// If we can't get a region, see if it's something we /know/ isn't a
// C string. In the context of locations, the only time we can issue such
// a warning is for labels.
if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&Buf)) {
if (llvm::Optional<loc::GotoLabel> Label = Buf.getAs<loc::GotoLabel>()) {
if (!Filter.CheckCStringNotNullTerm)
return UndefinedVal();
@ -798,14 +796,14 @@ const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
ProgramStateRef CStringChecker::InvalidateBuffer(CheckerContext &C,
ProgramStateRef state,
const Expr *E, SVal V) {
Loc *L = dyn_cast<Loc>(&V);
llvm::Optional<Loc> L = V.getAs<Loc>();
if (!L)
return state;
// FIXME: This is a simplified version of what's in CFRefCount.cpp -- it makes
// some assumptions about the value that CFRefCount can't. Even so, it should
// probably be refactored.
if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(L)) {
if (llvm::Optional<loc::MemRegionVal> MR = L->getAs<loc::MemRegionVal>()) {
const MemRegion *R = MR->getRegion()->StripCasts();
// Are we dealing with an ElementRegion? If so, we should be invalidating
@ -929,16 +927,13 @@ void CStringChecker::evalCopyCommon(CheckerContext &C,
// If this is mempcpy, get the byte after the last byte copied and
// bind the expr.
if (IsMempcpy) {
loc::MemRegionVal *destRegVal = dyn_cast<loc::MemRegionVal>(&destVal);
assert(destRegVal && "Destination should be a known MemRegionVal here");
loc::MemRegionVal destRegVal = destVal.castAs<loc::MemRegionVal>();
// Get the length to copy.
NonLoc *lenValNonLoc = dyn_cast<NonLoc>(&sizeVal);
if (lenValNonLoc) {
if (llvm::Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) {
// Get the byte after the last byte copied.
SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
*destRegVal,
destRegVal,
*lenValNonLoc,
Dest->getType());
@ -1054,9 +1049,9 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
// First, get the two buffers' addresses. Another checker will have already
// made sure they're not undefined.
DefinedOrUnknownSVal LV =
cast<DefinedOrUnknownSVal>(state->getSVal(Left, LCtx));
state->getSVal(Left, LCtx).castAs<DefinedOrUnknownSVal>();
DefinedOrUnknownSVal RV =
cast<DefinedOrUnknownSVal>(state->getSVal(Right, LCtx));
state->getSVal(Right, LCtx).castAs<DefinedOrUnknownSVal>();
// See if they are the same.
DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
@ -1166,19 +1161,17 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
const Expr *maxlenExpr = CE->getArg(1);
SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
NonLoc *maxlenValNL = dyn_cast<NonLoc>(&maxlenVal);
llvm::Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
llvm::Optional<NonLoc> maxlenValNL = maxlenVal.getAs<NonLoc>();
if (strLengthNL && maxlenValNL) {
ProgramStateRef stateStringTooLong, stateStringNotTooLong;
// Check if the strLength is greater than the maxlen.
llvm::tie(stateStringTooLong, stateStringNotTooLong) =
state->assume(cast<DefinedOrUnknownSVal>
(C.getSValBuilder().evalBinOpNN(state, BO_GT,
*strLengthNL,
*maxlenValNL,
cmpTy)));
state->assume(C.getSValBuilder().evalBinOpNN(
state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
.castAs<DefinedOrUnknownSVal>());
if (stateStringTooLong && !stateStringNotTooLong) {
// If the string is longer than maxlen, return maxlen.
@ -1195,28 +1188,24 @@ void CStringChecker::evalstrLengthCommon(CheckerContext &C, const CallExpr *CE,
// All we know is the return value is the min of the string length
// and the limit. This is better than nothing.
result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
NonLoc *resultNL = cast<NonLoc>(&result);
NonLoc resultNL = result.castAs<NonLoc>();
if (strLengthNL) {
state = state->assume(cast<DefinedOrUnknownSVal>
(C.getSValBuilder().evalBinOpNN(state, BO_LE,
*resultNL,
*strLengthNL,
cmpTy)), true);
state = state->assume(C.getSValBuilder().evalBinOpNN(
state, BO_LE, resultNL, *strLengthNL, cmpTy)
.castAs<DefinedOrUnknownSVal>(), true);
}
if (maxlenValNL) {
state = state->assume(cast<DefinedOrUnknownSVal>
(C.getSValBuilder().evalBinOpNN(state, BO_LE,
*resultNL,
*maxlenValNL,
cmpTy)), true);
state = state->assume(C.getSValBuilder().evalBinOpNN(
state, BO_LE, resultNL, *maxlenValNL, cmpTy)
.castAs<DefinedOrUnknownSVal>(), true);
}
}
} else {
// This is a plain strlen(), not strnlen().
result = cast<DefinedOrUnknownSVal>(strLength);
result = strLength.castAs<DefinedOrUnknownSVal>();
// If we don't know the length of the string, conjure a return
// value, so it can be used in constraints, at least.
@ -1335,8 +1324,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// Protect against misdeclared strncpy().
lenVal = svalBuilder.evalCast(lenVal, sizeTy, lenExpr->getType());
NonLoc *strLengthNL = dyn_cast<NonLoc>(&strLength);
NonLoc *lenValNL = dyn_cast<NonLoc>(&lenVal);
llvm::Optional<NonLoc> strLengthNL = strLength.getAs<NonLoc>();
llvm::Optional<NonLoc> lenValNL = lenVal.getAs<NonLoc>();
// If we know both values, we might be able to figure out how much
// we're copying.
@ -1346,10 +1335,9 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// Check if the max number to copy is less than the length of the src.
// If the bound is equal to the source length, strncpy won't null-
// terminate the result!
llvm::tie(stateSourceTooLong, stateSourceNotTooLong) =
state->assume(cast<DefinedOrUnknownSVal>
(svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL,
*lenValNL, cmpTy)));
llvm::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy)
.castAs<DefinedOrUnknownSVal>());
if (stateSourceTooLong && !stateSourceNotTooLong) {
// Max number to copy is less than the length of the src, so the actual
@ -1376,7 +1364,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (dstStrLength.isUndef())
return;
if (NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength)) {
if (llvm::Optional<NonLoc> dstStrLengthNL =
dstStrLength.getAs<NonLoc>()) {
maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Add,
*lenValNL,
*dstStrLengthNL,
@ -1407,7 +1396,7 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// Otherwise, go ahead and figure out the last element we'll touch.
// We don't record the non-zero assumption here because we can't
// be sure. We won't warn on a possible zero.
NonLoc one = cast<NonLoc>(svalBuilder.makeIntVal(1, sizeTy));
NonLoc one = svalBuilder.makeIntVal(1, sizeTy).castAs<NonLoc>();
maxLastElementIndex = svalBuilder.evalBinOpNN(state, BO_Sub, *lenValNL,
one, sizeTy);
boundWarning = "Size argument is greater than the length of the "
@ -1425,15 +1414,16 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
amountCopied = getCStringLength(C, state, lenExpr, srcVal, true);
assert(!amountCopied.isUndef());
if (NonLoc *amountCopiedNL = dyn_cast<NonLoc>(&amountCopied)) {
if (llvm::Optional<NonLoc> amountCopiedNL =
amountCopied.getAs<NonLoc>()) {
if (lenValNL) {
// amountCopied <= lenVal
SVal copiedLessThanBound = svalBuilder.evalBinOpNN(state, BO_LE,
*amountCopiedNL,
*lenValNL,
cmpTy);
state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanBound),
true);
state = state->assume(
copiedLessThanBound.castAs<DefinedOrUnknownSVal>(), true);
if (!state)
return;
}
@ -1444,8 +1434,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
*amountCopiedNL,
*strLengthNL,
cmpTy);
state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
true);
state = state->assume(
copiedLessThanSrc.castAs<DefinedOrUnknownSVal>(), true);
if (!state)
return;
}
@ -1475,8 +1465,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
if (dstStrLength.isUndef())
return;
NonLoc *srcStrLengthNL = dyn_cast<NonLoc>(&amountCopied);
NonLoc *dstStrLengthNL = dyn_cast<NonLoc>(&dstStrLength);
llvm::Optional<NonLoc> srcStrLengthNL = amountCopied.getAs<NonLoc>();
llvm::Optional<NonLoc> dstStrLengthNL = dstStrLength.getAs<NonLoc>();
// If we know both string lengths, we might know the final string length.
if (srcStrLengthNL && dstStrLengthNL) {
@ -1497,14 +1487,15 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
finalStrLength = getCStringLength(C, state, CE, DstVal, true);
assert(!finalStrLength.isUndef());
if (NonLoc *finalStrLengthNL = dyn_cast<NonLoc>(&finalStrLength)) {
if (llvm::Optional<NonLoc> finalStrLengthNL =
finalStrLength.getAs<NonLoc>()) {
if (srcStrLengthNL) {
// finalStrLength >= srcStrLength
SVal sourceInResult = svalBuilder.evalBinOpNN(state, BO_GE,
*finalStrLengthNL,
*srcStrLengthNL,
cmpTy);
state = state->assume(cast<DefinedOrUnknownSVal>(sourceInResult),
state = state->assume(sourceInResult.castAs<DefinedOrUnknownSVal>(),
true);
if (!state)
return;
@ -1516,8 +1507,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
*finalStrLengthNL,
*dstStrLengthNL,
cmpTy);
state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
true);
state =
state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true);
if (!state)
return;
}
@ -1538,13 +1529,15 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
// If the destination is a MemRegion, try to check for a buffer overflow and
// record the new string length.
if (loc::MemRegionVal *dstRegVal = dyn_cast<loc::MemRegionVal>(&DstVal)) {
if (llvm::Optional<loc::MemRegionVal> dstRegVal =
DstVal.getAs<loc::MemRegionVal>()) {
QualType ptrTy = Dst->getType();
// If we have an exact value on a bounded copy, use that to check for
// overflows, rather than our estimate about how much is actually copied.
if (boundWarning) {
if (NonLoc *maxLastNL = dyn_cast<NonLoc>(&maxLastElementIndex)) {
if (llvm::Optional<NonLoc> maxLastNL =
maxLastElementIndex.getAs<NonLoc>()) {
SVal maxLastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
*maxLastNL, ptrTy);
state = CheckLocation(C, state, CE->getArg(2), maxLastElement,
@ -1555,7 +1548,8 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
}
// Then, if the final length is known...
if (NonLoc *knownStrLength = dyn_cast<NonLoc>(&finalStrLength)) {
if (llvm::Optional<NonLoc> knownStrLength =
finalStrLength.getAs<NonLoc>()) {
SVal lastElement = svalBuilder.evalBinOpLN(state, BO_Add, *dstRegVal,
*knownStrLength, ptrTy);
@ -1673,8 +1667,8 @@ void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallExpr *CE,
// If we know the two buffers are the same, we know the result is 0.
// First, get the two buffers' addresses. Another checker will have already
// made sure they're not undefined.
DefinedOrUnknownSVal LV = cast<DefinedOrUnknownSVal>(s1Val);
DefinedOrUnknownSVal RV = cast<DefinedOrUnknownSVal>(s2Val);
DefinedOrUnknownSVal LV = s1Val.castAs<DefinedOrUnknownSVal>();
DefinedOrUnknownSVal RV = s2Val.castAs<DefinedOrUnknownSVal>();
// See if they are the same.
SValBuilder &svalBuilder = C.getSValBuilder();
@ -1859,8 +1853,8 @@ void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
SVal StrVal = state->getSVal(Init, C.getLocationContext());
assert(StrVal.isValid() && "Initializer string is unknown or undefined");
DefinedOrUnknownSVal strLength
= cast<DefinedOrUnknownSVal>(getCStringLength(C, state, Init, StrVal));
DefinedOrUnknownSVal strLength =
getCStringLength(C, state, Init, StrVal).castAs<DefinedOrUnknownSVal>();
state = state->set<CStringLength>(MR, strLength);
}

Просмотреть файл

@ -133,9 +133,9 @@ bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
if (!checkUninitFields)
return false;
if (const nonloc::LazyCompoundVal *LV =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
if (llvm::Optional<nonloc::LazyCompoundVal> LV =
V.getAs<nonloc::LazyCompoundVal>()) {
class FindUninitializedField {
public:
@ -236,7 +236,8 @@ void CallAndMessageChecker::checkPreStmt(const CallExpr *CE,
}
ProgramStateRef StNonNull, StNull;
llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(L));
llvm::tie(StNonNull, StNull) =
State->assume(L.castAs<DefinedOrUnknownSVal>());
if (StNull && !StNonNull) {
if (!BT_call_null)
@ -265,7 +266,8 @@ void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
}
ProgramStateRef StNonNull, StNull;
llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
llvm::tie(StNonNull, StNull) =
State->assume(V.castAs<DefinedOrUnknownSVal>());
if (StNull && !StNonNull) {
if (!BT_cxx_call_null)
@ -344,7 +346,7 @@ void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
return;
} else {
// Bifurcate the state into nil and non-nil ones.
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
DefinedOrUnknownSVal receiverVal = recVal.castAs<DefinedOrUnknownSVal>();
ProgramStateRef state = C.getState();
ProgramStateRef notNilState, nilState;

Просмотреть файл

@ -183,10 +183,10 @@ void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
return;
}
DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(l);
DefinedOrUnknownSVal location = l.castAs<DefinedOrUnknownSVal>();
// Check for null dereferences.
if (!isa<Loc>(location))
if (!location.getAs<Loc>())
return;
ProgramStateRef state = C.getState();
@ -231,7 +231,8 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
ProgramStateRef State = C.getState();
ProgramStateRef StNonNull, StNull;
llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
llvm::tie(StNonNull, StNull) =
State->assume(V.castAs<DefinedOrUnknownSVal>());
if (StNull) {
if (!StNonNull) {

Просмотреть файл

@ -58,7 +58,7 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
return;
SVal Denom = C.getState()->getSVal(B->getRHS(), C.getLocationContext());
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
llvm::Optional<DefinedSVal> DV = Denom.getAs<DefinedSVal>();
// Divide-by-undefined handled in the generic checking for uses of
// undefined values.

Просмотреть файл

@ -65,7 +65,7 @@ static const char *getArgumentValueString(const CallExpr *CE,
ProgramStateRef StTrue, StFalse;
llvm::tie(StTrue, StFalse) =
State->assume(cast<DefinedOrUnknownSVal>(AssertionVal));
State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>());
if (StTrue) {
if (StFalse)

Просмотреть файл

@ -431,7 +431,7 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
if (AddrVal.isUnknownOrUndef())
return 0;
Loc *AddrLoc = dyn_cast<Loc>(&AddrVal);
llvm::Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
if (!AddrLoc)
return 0;

Просмотреть файл

@ -173,11 +173,11 @@ void IdempotentOperationChecker::checkPreStmt(const BinaryOperator *B,
case BO_ShrAssign:
case BO_Assign:
// Assign statements have one extra level of indirection
if (!isa<Loc>(LHSVal)) {
if (!LHSVal.getAs<Loc>()) {
A = Impossible;
return;
}
LHSVal = state->getSVal(cast<Loc>(LHSVal), LHS->getType());
LHSVal = state->getSVal(LHSVal.castAs<Loc>(), LHS->getType());
}

Просмотреть файл

@ -217,7 +217,7 @@ static SymbolRef getAsPointeeSymbol(const Expr *Expr,
ProgramStateRef State = C.getState();
SVal ArgV = State->getSVal(Expr, C.getLocationContext());
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&ArgV)) {
if (llvm::Optional<loc::MemRegionVal> X = ArgV.getAs<loc::MemRegionVal>()) {
StoreManager& SM = C.getStoreManager();
SymbolRef sym = SM.getBinding(State->getStore(), *X).getAsLocSymbol();
if (sym)
@ -421,7 +421,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
// If the buffer can be null and the return status can be an error,
// report a bad call to free.
if (State->assume(cast<DefinedSVal>(ArgSVal), false) &&
if (State->assume(ArgSVal.castAs<DefinedSVal>(), false) &&
!definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
ExplodedNode *N = C.addTransition(State);
if (!N)

Просмотреть файл

@ -555,12 +555,12 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
unsigned Count = C.blockCount();
SValBuilder &svalBuilder = C.getSValBuilder();
const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
DefinedSVal RetVal =
cast<DefinedSVal>(svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count));
DefinedSVal RetVal = svalBuilder.getConjuredHeapSymbolVal(CE, LCtx, Count)
.castAs<DefinedSVal>();
state = state->BindExpr(CE, C.getLocationContext(), RetVal);
// We expect the malloc functions to return a pointer.
if (!isa<Loc>(RetVal))
if (!RetVal.getAs<Loc>())
return 0;
// Fill the region with the initialization value.
@ -571,12 +571,12 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
if (!R)
return 0;
if (isa<DefinedOrUnknownSVal>(Size)) {
if (llvm::Optional<DefinedOrUnknownSVal> DefinedSize =
Size.getAs<DefinedOrUnknownSVal>()) {
SValBuilder &svalBuilder = C.getSValBuilder();
DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
DefinedOrUnknownSVal extentMatchesSize =
svalBuilder.evalEQ(state, Extent, DefinedSize);
svalBuilder.evalEQ(state, Extent, *DefinedSize);
state = state->assume(extentMatchesSize, true);
assert(state);
@ -592,7 +592,7 @@ ProgramStateRef MallocChecker::MallocUpdateRefState(CheckerContext &C,
SVal retVal = state->getSVal(CE, C.getLocationContext());
// We expect the malloc functions to return a pointer.
if (!isa<Loc>(retVal))
if (!retVal.getAs<Loc>())
return 0;
SymbolRef Sym = retVal.getAsLocSymbol();
@ -661,12 +661,12 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
bool ReturnsNullOnFailure) const {
SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
if (!isa<DefinedOrUnknownSVal>(ArgVal))
if (!ArgVal.getAs<DefinedOrUnknownSVal>())
return 0;
DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
// Check for null dereferences.
if (!isa<Loc>(location))
if (!location.getAs<Loc>())
return 0;
// The explicit NULL case, no operation is performed.
@ -782,11 +782,13 @@ ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
}
bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
if (llvm::Optional<nonloc::ConcreteInt> IntVal =
V.getAs<nonloc::ConcreteInt>())
os << "an integer (" << IntVal->getValue() << ")";
else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
else if (llvm::Optional<loc::ConcreteInt> ConstAddr =
V.getAs<loc::ConcreteInt>())
os << "a constant address (" << ConstAddr->getValue() << ")";
else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
else if (llvm::Optional<loc::GotoLabel> Label = V.getAs<loc::GotoLabel>())
os << "the address of the label '" << Label->getLabel()->getName() << "'";
else
return false;
@ -952,9 +954,9 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
const Expr *arg0Expr = CE->getArg(0);
const LocationContext *LCtx = C.getLocationContext();
SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
if (!isa<DefinedOrUnknownSVal>(Arg0Val))
if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
return 0;
DefinedOrUnknownSVal arg0Val = cast<DefinedOrUnknownSVal>(Arg0Val);
DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
SValBuilder &svalBuilder = C.getSValBuilder();
@ -968,9 +970,9 @@ ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
// Get the value of the size argument.
SVal Arg1ValG = state->getSVal(Arg1, LCtx);
if (!isa<DefinedOrUnknownSVal>(Arg1ValG))
if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
return 0;
DefinedOrUnknownSVal Arg1Val = cast<DefinedOrUnknownSVal>(Arg1ValG);
DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
// Compare the size argument to 0.
DefinedOrUnknownSVal SizeZero =

Просмотреть файл

@ -186,7 +186,7 @@ static void setFlag(ProgramStateRef state, SVal val, CheckerContext &C) {
static QualType parameterTypeFromSVal(SVal val, CheckerContext &C) {
const StackFrameContext *
SFC = C.getLocationContext()->getCurrentStackFrame();
if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(&val)) {
if (llvm::Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>()) {
const MemRegion* R = X->getRegion();
if (const VarRegion *VR = R->getAs<VarRegion>())
if (const StackArgumentsSpaceRegion *
@ -203,7 +203,7 @@ void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad,
CheckerContext &C) const {
if (!isLoad)
return;
if (loc.isUndef() || !isa<Loc>(loc))
if (loc.isUndef() || !loc.getAs<Loc>())
return;
ASTContext &Ctx = C.getASTContext();
@ -225,12 +225,12 @@ void NSOrCFErrorDerefChecker::checkLocation(SVal loc, bool isLoad,
CFErrorII = &Ctx.Idents.get("CFErrorRef");
if (ShouldCheckNSError && IsNSError(parmT, NSErrorII)) {
setFlag<NSErrorOut>(state, state->getSVal(cast<Loc>(loc)), C);
setFlag<NSErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C);
return;
}
if (ShouldCheckCFError && IsCFError(parmT, CFErrorII)) {
setFlag<CFErrorOut>(state, state->getSVal(cast<Loc>(loc)), C);
setFlag<CFErrorOut>(state, state->getSVal(loc.castAs<Loc>()), C);
return;
}
}

Просмотреть файл

@ -42,7 +42,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
SVal V = state->getSVal(Ex, C.getLocationContext());
// Uninitialized value used for the mutex?
if (isa<UndefinedVal>(V)) {
if (V.getAs<UndefinedVal>()) {
if (ExplodedNode *N = C.generateSink()) {
if (!BT_undef)
BT_undef.reset(new BuiltinBug("Uninitialized value used as mutex "
@ -60,7 +60,7 @@ void ObjCAtSyncChecker::checkPreStmt(const ObjCAtSynchronizedStmt *S,
// Check for null mutexes.
ProgramStateRef notNullState, nullState;
llvm::tie(notNullState, nullState) = state->assume(cast<DefinedSVal>(V));
llvm::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
if (nullState) {
if (!notNullState) {

Просмотреть файл

@ -72,7 +72,8 @@ void ObjCContainersChecker::addSizeInfo(const Expr *Array, const Expr *Size,
if (!ArraySym)
return;
C.addTransition(State->set<ArraySizeMap>(ArraySym, cast<DefinedSVal>(SizeV)));
C.addTransition(
State->set<ArraySizeMap>(ArraySym, SizeV.castAs<DefinedSVal>()));
return;
}
@ -125,7 +126,7 @@ void ObjCContainersChecker::checkPreStmt(const CallExpr *CE,
SVal IdxVal = State->getSVal(IdxExpr, C.getLocationContext());
if (IdxVal.isUnknownOrUndef())
return;
DefinedSVal Idx = cast<DefinedSVal>(IdxVal);
DefinedSVal Idx = IdxVal.castAs<DefinedSVal>();
// Now, check if 'Idx in [0, Size-1]'.
const QualType T = IdxExpr->getType();

Просмотреть файл

@ -255,7 +255,7 @@ void ObjCSelfInitChecker::checkPreCall(const CallEvent &CE,
for (unsigned i = 0; i < NumArgs; ++i) {
SVal argV = CE.getArgSVal(i);
if (isSelfVar(argV, C)) {
unsigned selfFlags = getSelfFlags(state->getSVal(cast<Loc>(argV)), C);
unsigned selfFlags = getSelfFlags(state->getSVal(argV.castAs<Loc>()), C);
C.addTransition(state->set<PreCallSelfFlags>(selfFlags));
return;
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
@ -286,7 +286,7 @@ void ObjCSelfInitChecker::checkPostCall(const CallEvent &CE,
// If the address of 'self' is being passed to the call, assume that the
// 'self' after the call will have the same flags.
// EX: log(&self)
addSelfFlag(state, state->getSVal(cast<Loc>(argV)), prevFlags, C);
addSelfFlag(state, state->getSVal(argV.castAs<Loc>()), prevFlags, C);
return;
} else if (hasSelfFlag(argV, SelfFlag_Self, C)) {
// If 'self' is passed to the call by value, assume that the function
@ -312,7 +312,8 @@ void ObjCSelfInitChecker::checkLocation(SVal location, bool isLoad,
// value is the object that 'self' points to.
ProgramStateRef state = C.getState();
if (isSelfVar(location, C))
addSelfFlag(state, state->getSVal(cast<Loc>(location)), SelfFlag_Self, C);
addSelfFlag(state, state->getSVal(location.castAs<Loc>()), SelfFlag_Self,
C);
}
@ -417,10 +418,10 @@ static bool isSelfVar(SVal location, CheckerContext &C) {
AnalysisDeclContext *analCtx = C.getCurrentAnalysisDeclContext();
if (!analCtx->getSelfDecl())
return false;
if (!isa<loc::MemRegionVal>(location))
if (!location.getAs<loc::MemRegionVal>())
return false;
loc::MemRegionVal MRV = cast<loc::MemRegionVal>(location);
loc::MemRegionVal MRV = location.castAs<loc::MemRegionVal>();
if (const DeclRegion *DR = dyn_cast<DeclRegion>(MRV.stripCasts()))
return (DR->getDecl() == analCtx->getSelfDecl());

Просмотреть файл

@ -98,7 +98,7 @@ void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
if (X.isUnknownOrUndef())
return;
DefinedSVal retVal = cast<DefinedSVal>(X);
DefinedSVal retVal = X.castAs<DefinedSVal>();
if (state->contains<LockSet>(lockR)) {
if (!BT_doublelock)

Просмотреть файл

@ -3361,7 +3361,8 @@ void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
// does not understand.
ProgramStateRef state = C.getState();
if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&loc)) {
if (llvm::Optional<loc::MemRegionVal> regionLoc =
loc.getAs<loc::MemRegionVal>()) {
escapes = !regionLoc->getRegion()->hasStackStorage();
if (!escapes) {

Просмотреть файл

@ -210,9 +210,8 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const {
ProgramStateRef state = C.getState();
SValBuilder &svalBuilder = C.getSValBuilder();
const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
DefinedSVal RetVal =
cast<DefinedSVal>(svalBuilder.conjureSymbolVal(0, CE, LCtx,
C.blockCount()));
DefinedSVal RetVal = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount())
.castAs<DefinedSVal>();
state = state->BindExpr(CE, C.getLocationContext(), RetVal);
ConstraintManager &CM = C.getConstraintManager();
@ -260,7 +259,7 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const {
return;
// Check the legality of the 'whence' argument of 'fseek'.
SVal Whence = state->getSVal(CE->getArg(2), C.getLocationContext());
const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Whence);
llvm::Optional<nonloc::ConcreteInt> CI = Whence.getAs<nonloc::ConcreteInt>();
if (!CI)
return;
@ -338,7 +337,7 @@ void StreamChecker::Fileno(CheckerContext &C, const CallExpr *CE) const {
ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state,
CheckerContext &C) const {
const DefinedSVal *DV = dyn_cast<DefinedSVal>(&SV);
llvm::Optional<DefinedSVal> DV = SV.getAs<DefinedSVal>();
if (!DV)
return 0;

Просмотреть файл

@ -103,21 +103,20 @@ void UnixAPIChecker::CheckOpen(CheckerContext &C, const CallExpr *CE) const {
// Now check if oflags has O_CREAT set.
const Expr *oflagsEx = CE->getArg(1);
const SVal V = state->getSVal(oflagsEx, C.getLocationContext());
if (!isa<NonLoc>(V)) {
if (!V.getAs<NonLoc>()) {
// The case where 'V' can be a location can only be due to a bad header,
// so in this case bail out.
return;
}
NonLoc oflags = cast<NonLoc>(V);
NonLoc ocreateFlag =
cast<NonLoc>(C.getSValBuilder().makeIntVal(Val_O_CREAT.getValue(),
oflagsEx->getType()));
NonLoc oflags = V.castAs<NonLoc>();
NonLoc ocreateFlag = C.getSValBuilder()
.makeIntVal(Val_O_CREAT.getValue(), oflagsEx->getType()).castAs<NonLoc>();
SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
oflags, ocreateFlag,
oflagsEx->getType());
if (maskedFlagsUC.isUnknownOrUndef())
return;
DefinedSVal maskedFlags = cast<DefinedSVal>(maskedFlagsUC);
DefinedSVal maskedFlags = maskedFlagsUC.castAs<DefinedSVal>();
// Check if maskedFlags is non-zero.
ProgramStateRef trueState, falseState;
@ -202,7 +201,7 @@ static bool IsZeroByteAllocation(ProgramStateRef state,
ProgramStateRef *trueState,
ProgramStateRef *falseState) {
llvm::tie(*trueState, *falseState) =
state->assume(cast<DefinedSVal>(argVal));
state->assume(argVal.castAs<DefinedSVal>());
return (*falseState && !*trueState);
}

Просмотреть файл

@ -110,7 +110,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
}
// Check if the size is zero.
DefinedSVal sizeD = cast<DefinedSVal>(sizeV);
DefinedSVal sizeD = sizeV.castAs<DefinedSVal>();
ProgramStateRef stateNotZero, stateZero;
llvm::tie(stateNotZero, stateZero) = state->assume(sizeD);
@ -130,22 +130,22 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
// Convert the array length to size_t.
SValBuilder &svalBuilder = C.getSValBuilder();
QualType SizeTy = Ctx.getSizeType();
NonLoc ArrayLength = cast<NonLoc>(svalBuilder.evalCast(sizeD, SizeTy,
SE->getType()));
NonLoc ArrayLength =
svalBuilder.evalCast(sizeD, SizeTy, SE->getType()).castAs<NonLoc>();
// Get the element size.
CharUnits EleSize = Ctx.getTypeSizeInChars(VLA->getElementType());
SVal EleSizeVal = svalBuilder.makeIntVal(EleSize.getQuantity(), SizeTy);
// Multiply the array length by the element size.
SVal ArraySizeVal = svalBuilder.evalBinOpNN(state, BO_Mul, ArrayLength,
cast<NonLoc>(EleSizeVal), SizeTy);
SVal ArraySizeVal = svalBuilder.evalBinOpNN(
state, BO_Mul, ArrayLength, EleSizeVal.castAs<NonLoc>(), SizeTy);
// Finally, assume that the array's extent matches the given size.
const LocationContext *LC = C.getLocationContext();
DefinedOrUnknownSVal Extent =
state->getRegion(VD, LC)->getExtent(svalBuilder);
DefinedOrUnknownSVal ArraySize = cast<DefinedOrUnknownSVal>(ArraySizeVal);
DefinedOrUnknownSVal ArraySize = ArraySizeVal.castAs<DefinedOrUnknownSVal>();
DefinedOrUnknownSVal sizeIsKnown =
svalBuilder.evalEQ(state, Extent, ArraySize);
state = state->assume(sizeIsKnown, true);

Просмотреть файл

@ -228,7 +228,7 @@ public:
// If we can't prove the return value is 0, just mark it interesting, and
// make sure to track it into any further inner functions.
if (State->assume(cast<DefinedSVal>(V), true)) {
if (State->assume(V.castAs<DefinedSVal>(), true)) {
BR.markInteresting(V);
ReturnVisitor::addVisitorIfNecessary(N, RetE, BR);
return 0;
@ -241,7 +241,7 @@ public:
SmallString<64> Msg;
llvm::raw_svector_ostream Out(Msg);
if (isa<Loc>(V)) {
if (V.getAs<Loc>()) {
// If we are pruning null-return paths as unlikely error paths, mark the
// report invalid. We still want to emit a path note, however, in case
// the report is resurrected as valid later on.
@ -298,7 +298,7 @@ public:
CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
SVal ArgV = Call->getArgSVal(I);
if (!isa<Loc>(ArgV))
if (!ArgV.getAs<Loc>())
continue;
const Expr *ArgE = Call->getArgExpr(I);
@ -306,7 +306,7 @@ public:
continue;
// Is it possible for this argument to be non-null?
if (State->assume(cast<Loc>(ArgV), true))
if (State->assume(ArgV.castAs<Loc>(), true))
continue;
if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true))
@ -415,7 +415,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
// If we have an expression that provided the value, try to track where it
// came from.
if (InitE) {
if (V.isUndef() || isa<loc::ConcreteInt>(V)) {
if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
if (!IsParam)
InitE = InitE->IgnoreParenCasts();
bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam);
@ -462,7 +462,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
os << "Variable '" << *VR->getDecl() << "' ";
if (isa<loc::ConcreteInt>(V)) {
if (V.getAs<loc::ConcreteInt>()) {
bool b = false;
if (R->isBoundable()) {
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@ -475,9 +475,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (!b)
os << action << "a null pointer value";
}
else if (isa<nonloc::ConcreteInt>(V)) {
os << action << cast<nonloc::ConcreteInt>(V).getValue();
} else if (llvm::Optional<nonloc::ConcreteInt> CVal =
V.getAs<nonloc::ConcreteInt>()) {
os << action << CVal->getValue();
}
else if (DS) {
if (V.isUndef()) {
@ -499,15 +499,16 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
os << "Passing ";
if (isa<loc::ConcreteInt>(V)) {
if (V.getAs<loc::ConcreteInt>()) {
if (Param->getType()->isObjCObjectPointerType())
os << "nil object reference";
else
os << "null pointer value";
} else if (V.isUndef()) {
os << "uninitialized value";
} else if (isa<nonloc::ConcreteInt>(V)) {
os << "the value " << cast<nonloc::ConcreteInt>(V).getValue();
} else if (llvm::Optional<nonloc::ConcreteInt> CI =
V.getAs<nonloc::ConcreteInt>()) {
os << "the value " << CI->getValue();
} else {
os << "value";
}
@ -521,7 +522,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
}
if (os.str().empty()) {
if (isa<loc::ConcreteInt>(V)) {
if (V.getAs<loc::ConcreteInt>()) {
bool b = false;
if (R->isBoundable()) {
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@ -537,10 +538,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
}
else if (V.isUndef()) {
os << "Uninitialized value stored to ";
}
else if (isa<nonloc::ConcreteInt>(V)) {
os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
<< " is assigned to ";
} else if (llvm::Optional<nonloc::ConcreteInt> CV =
V.getAs<nonloc::ConcreteInt>()) {
os << "The value " << CV->getValue() << " is assigned to ";
}
else
os << "Value assigned to ";
@ -601,7 +601,7 @@ TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
if (isa<Loc>(Constraint)) {
if (Constraint.getAs<Loc>()) {
os << "Assuming pointer value is ";
os << (Assumption ? "non-null" : "null");
}
@ -693,8 +693,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
// If the contents are symbolic, find out when they became null.
if (V.getAsLocSymbol()) {
BugReporterVisitor *ConstraintTracker
= new TrackConstraintBRVisitor(cast<DefinedSVal>(V), false);
BugReporterVisitor *ConstraintTracker =
new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
report.addVisitor(ConstraintTracker);
}
@ -713,7 +713,7 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
// assert(!V.isUnknownOrUndef());
// Is it a symbolic value?
if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
if (llvm::Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
// At this point we are dealing with the region's LValue.
// However, if the rvalue is a symbolic region, we should track it as well.
SVal RVal = state->getSVal(L->getRegion());
@ -766,7 +766,7 @@ PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
return 0;
ProgramStateRef state = N->getState();
const SVal &V = state->getSVal(Receiver, N->getLocationContext());
const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
llvm::Optional<DefinedOrUnknownSVal> DV = V.getAs<DefinedOrUnknownSVal>();
if (!DV)
return 0;
state = state->assume(*DV, true);
@ -806,7 +806,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
// What did we load?
SVal V = state->getSVal(S, N->getLocationContext());
if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
// Register a new visitor with the BugReport.
BR.addVisitor(new FindLastStoreBRVisitor(V, R));
}

Просмотреть файл

@ -156,9 +156,10 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
// If we are passing a location wrapped as an integer, unwrap it and
// invalidate the values referred by the location.
if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
if (llvm::Optional<nonloc::LocAsInteger> Wrapped =
V.getAs<nonloc::LocAsInteger>())
V = Wrapped->getLoc();
else if (!isa<Loc>(V))
else if (!V.getAs<Loc>())
continue;
if (const MemRegion *R = V.getAsRegion()) {
@ -419,7 +420,7 @@ SVal CXXInstanceCall::getCXXThisVal() const {
return UnknownVal();
SVal ThisVal = getSVal(Base);
assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
assert(ThisVal.isUnknownOrUndef() || ThisVal.getAs<Loc>());
return ThisVal;
}

Просмотреть файл

@ -198,10 +198,8 @@ EnvironmentManager::removeDeadBindings(Environment Env,
EBMapRef = EBMapRef.add(BlkExpr, X);
// If the block expr's value is a memory region, then mark that region.
if (isa<loc::MemRegionVal>(X)) {
const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
SymReaper.markLive(R);
}
if (llvm::Optional<loc::MemRegionVal> R = X.getAs<loc::MemRegionVal>())
SymReaper.markLive(R->getRegion());
// Mark all symbols in the block expr's value live.
RSScaner.scan(X);

Просмотреть файл

@ -118,8 +118,8 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
svalBuilder.makeZeroVal(T),
getContext().IntTy);
DefinedOrUnknownSVal *Constraint =
dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
llvm::Optional<DefinedOrUnknownSVal> Constraint =
Constraint_untested.getAs<DefinedOrUnknownSVal>();
if (!Constraint)
break;
@ -138,7 +138,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
const MemRegion *R = state->getRegion(SelfD, InitLoc);
SVal V = state->getSVal(loc::MemRegionVal(R));
if (const Loc *LV = dyn_cast<Loc>(&V)) {
if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
// Assume that the pointer value in 'self' is non-null.
state = state->assume(*LV, true);
assert(state && "'self' cannot be null");
@ -154,7 +154,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
if (SFC->getParent() == 0) {
loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
SVal V = state->getSVal(L);
if (const Loc *LV = dyn_cast<Loc>(&V)) {
if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
state = state->assume(*LV, true);
assert(state && "'this' cannot be null");
}
@ -172,7 +172,7 @@ static ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
const Expr *E) {
SVal V = State->getSVal(E, LC);
if (isa<NonLoc>(V)) {
if (V.getAs<NonLoc>()) {
MemRegionManager &MRMgr = State->getStateManager().getRegionManager();
const MemRegion *R = MRMgr.getCXXTempObjectRegion(E, LC);
State = State->bindLoc(loc::MemRegionVal(R), V);
@ -472,8 +472,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst);
VisitCXXDestructor(varType, dest.castAs<loc::MemRegionVal>().getRegion(),
Dtor.getTriggerStmt(), /*IsBase=*/ false, Pred, Dst);
}
void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
@ -490,8 +490,8 @@ void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
QualType BaseTy = D.getBaseSpecifier()->getType();
SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
CurDtor->getBody(), /*IsBase=*/true, Pred, Dst);
VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(),
CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst);
}
void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
@ -503,10 +503,11 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
LCtx->getCurrentStackFrame());
SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
SVal FieldVal =
State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>());
VisitCXXDestructor(Member->getType(),
cast<loc::MemRegionVal>(FieldVal).getRegion(),
FieldVal.castAs<loc::MemRegionVal>().getRegion(),
CurDtor->getBody(), /*IsBase=*/false, Pred, Dst);
}
@ -1287,7 +1288,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
continue;
}
DefinedSVal V = cast<DefinedSVal>(X);
DefinedSVal V = X.castAs<DefinedSVal>();
ProgramStateRef StTrue, StFalse;
tie(StTrue, StFalse) = PrevState->assume(V);
@ -1327,8 +1328,8 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
typedef IndirectGotoNodeBuilder::iterator iterator;
if (isa<loc::GotoLabel>(V)) {
const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
if (llvm::Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) {
const LabelDecl *L = LV->getLabel();
for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
if (I.getLabel() == L) {
@ -1340,7 +1341,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
llvm_unreachable("No block with label.");
}
if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) {
// Dispatch to the first target and mark it as a sink.
//ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
// FIXME: add checker visit.
@ -1394,7 +1395,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
return;
}
DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
ProgramStateRef DefaultSt = state;
@ -1435,7 +1436,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
// If CondV evaluates to a constant, then we know that this
// is the *only* case that we can take, so stop evaluating the
// others.
if (isa<nonloc::ConcreteInt>(CondV))
if (CondV.getAs<nonloc::ConcreteInt>())
return;
}
@ -1529,7 +1530,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
// results in boolean contexts.
SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
currBldrCtx->blockCount());
state = state->assume(cast<DefinedOrUnknownSVal>(V), true);
state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
ProgramPoint::PostLValueKind);
return;
@ -1646,7 +1647,8 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
bool escapes = true;
// TODO: Move to StoreManager.
if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&Loc)) {
if (llvm::Optional<loc::MemRegionVal> regionLoc =
Loc.getAs<loc::MemRegionVal>()) {
escapes = !regionLoc->getRegion()->hasStackStorage();
if (!escapes) {
@ -1754,7 +1756,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
// If the location is not a 'Loc', it will already be handled by
// the checkers. There is nothing left to do.
if (!isa<Loc>(location)) {
if (!location.getAs<Loc>()) {
const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/0, /*tag*/0);
ProgramStateRef state = Pred->getState();
state = processPointerEscapedOnBind(state, location, Val);
@ -1773,11 +1775,12 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
// When binding the value, pass on the hint that this is a initialization.
// For initializations, we do not need to inform clients of region
// changes.
state = state->bindLoc(cast<Loc>(location),
state = state->bindLoc(location.castAs<Loc>(),
Val, /* notifyChanges = */ !atDeclInit);
const MemRegion *LocReg = 0;
if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) {
if (llvm::Optional<loc::MemRegionVal> LocRegVal =
location.getAs<loc::MemRegionVal>()) {
LocReg = LocRegVal->getRegion();
}
@ -1826,7 +1829,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
const ProgramPointTag *tag,
QualType LoadTy)
{
assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc.");
// Are we loading from a region? This actually results in two loads; one
// to fetch the address of the referenced value and one to fetch the
@ -1885,7 +1888,7 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
if (location.isValid()) {
if (LoadTy.isNull())
LoadTy = BoundEx->getType();
V = state->getSVal(cast<Loc>(location), LoadTy);
V = state->getSVal(location.castAs<Loc>(), LoadTy);
}
Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
@ -1955,7 +1958,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
ProgramStateRef state = Pred->getState();
SVal V = state->getSVal(Ex, Pred->getLocationContext());
nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
llvm::Optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
if (SEV && SEV->isExpression()) {
const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
geteagerlyAssumeBinOpBifurcationTags();
@ -1995,10 +1998,10 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
OE = A->end_outputs(); OI != OE; ++OI) {
SVal X = state->getSVal(*OI, Pred->getLocationContext());
assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
if (isa<Loc>(X))
state = state->bindLoc(cast<Loc>(X), UnknownVal());
if (llvm::Optional<Loc> LV = X.getAs<Loc>())
state = state->bindLoc(*LV, UnknownVal());
}
Bldr.generateNode(A, Pred, state);

Просмотреть файл

@ -67,12 +67,12 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
// TODO: This can be removed after we enable history tracking with
// SymSymExpr.
unsigned Count = currBldrCtx->blockCount();
if (isa<Loc>(LeftV) &&
if (LeftV.getAs<Loc>() &&
RHS->getType()->isIntegerType() && RightV.isUnknown()) {
RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(),
Count);
}
if (isa<Loc>(RightV) &&
if (RightV.getAs<Loc>() &&
LHS->getType()->isIntegerType() && LeftV.isUnknown()) {
LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(),
Count);
@ -480,10 +480,13 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
} else {
// We bound the temp obj region to the CXXConstructExpr. Now recover
// the lazy compound value when the variable is not a reference.
if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
!VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
assert(isa<nonloc::LazyCompoundVal>(InitVal));
if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
!VD->getType()->isReferenceType()) {
if (llvm::Optional<loc::MemRegionVal> M =
InitVal.getAs<loc::MemRegionVal>()) {
InitVal = state->getSVal(M->getRegion());
assert(InitVal.getAs<nonloc::LazyCompoundVal>());
}
}
// Recover some path-sensitivity if a scalar value evaluated to
@ -558,7 +561,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
if (RHSVal.isUndef()) {
X = RHSVal;
} else {
DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
DefinedOrUnknownSVal DefinedRHS = RHSVal.castAs<DefinedOrUnknownSVal>();
ProgramStateRef StTrue, StFalse;
llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
if (StTrue) {
@ -810,11 +813,11 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
llvm_unreachable("Invalid Opcode.");
case UO_Not:
// FIXME: Do we need to handle promotions?
state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
break;
case UO_Minus:
// FIXME: Do we need to handle promotions?
state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
break;
case UO_LNot:
// C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
@ -822,17 +825,16 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E".
SVal Result;
if (isa<Loc>(V)) {
if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
Loc X = svalBuilder.makeNull();
Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
U->getType());
Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
}
else if (Ex->getType()->isFloatingType()) {
// FIXME: handle floating point types.
Result = UnknownVal();
} else {
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
U->getType());
}
@ -874,7 +876,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
continue;
}
DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
// Handle all other values.
BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;

Просмотреть файл

@ -64,7 +64,7 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
SVal V = Call.getArgSVal(0);
// Make sure the value being copied is not unknown.
if (const Loc *L = dyn_cast<Loc>(&V))
if (llvm::Optional<Loc> L = V.getAs<Loc>())
V = Pred->getState()->getSVal(*L);
evalBind(Dst, CtorExpr, Pred, ThisVal, V, true);
@ -287,7 +287,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
if (CNE->isArray()) {
// FIXME: allocating an array requires simulating the constructors.
// For now, just return a symbolicated region.
const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
const ElementRegion *EleReg =
getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
@ -319,8 +319,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
(void)ObjTy;
assert(!ObjTy->isRecordType());
SVal Location = State->getSVal(CNE, LCtx);
if (isa<Loc>(Location))
State = State->bindLoc(cast<Loc>(Location), State->getSVal(Init, LCtx));
if (llvm::Optional<Loc> LV = Location.getAs<Loc>())
State = State->bindLoc(*LV, State->getSVal(Init, LCtx));
}
}

Просмотреть файл

@ -121,7 +121,7 @@ static std::pair<const Stmt*,
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
StoreManager &StoreMgr) {
// For now, the only adjustments we handle apply only to locations.
if (!isa<Loc>(V))
if (!V.getAs<Loc>())
return V;
// If the types already match, don't do any unnecessary work.
@ -266,7 +266,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// If the constructed object is a temporary prvalue, get its bindings.
if (isTemporaryPRValue(CCE, ThisV))
ThisV = state->getSVal(cast<Loc>(ThisV));
ThisV = state->getSVal(ThisV.castAs<Loc>());
state = state->BindExpr(CCE, callerCtx, ThisV);
}
@ -709,7 +709,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
// If the constructed object is a temporary prvalue, get its bindings.
if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
ThisV = State->getSVal(cast<Loc>(ThisV));
ThisV = State->getSVal(ThisV.castAs<Loc>());
return State->BindExpr(E, LCtx, ThisV);
}

Просмотреть файл

@ -103,8 +103,9 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
// Handle the case where the container has no elements.
SVal FalseV = svalBuilder.makeTruthVal(0);
ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
if (llvm::Optional<loc::MemRegionVal> MV =
elementV.getAs<loc::MemRegionVal>())
if (const TypedValueRegion *R =
dyn_cast<TypedValueRegion>(MV->getRegion())) {
// FIXME: The proper thing to do is to really iterate over the
@ -161,8 +162,9 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
SVal recVal = UpdatedMsg->getReceiverSVal();
if (!recVal.isUndef()) {
// Bifurcate the state into nil and non-nil ones.
DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
DefinedOrUnknownSVal receiverVal =
recVal.castAs<DefinedOrUnknownSVal>();
ProgramStateRef notNilState, nilState;
llvm::tie(notNilState, nilState) = State->assume(receiverVal);

Просмотреть файл

@ -1044,7 +1044,8 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const {
// FIXME: generalize to symbolic offsets.
SVal index = ER->getIndex();
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
if (llvm::Optional<nonloc::ConcreteInt> CI =
index.getAs<nonloc::ConcreteInt>()) {
// Update the offset.
int64_t i = CI->getValue().getSExtValue();
@ -1171,7 +1172,8 @@ RegionOffset MemRegion::getAsOffset() const {
}
SVal Index = ER->getIndex();
if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
if (llvm::Optional<nonloc::ConcreteInt> CI =
Index.getAs<nonloc::ConcreteInt>()) {
// Don't bother calculating precise offsets if we already have a
// symbolic offset somewhere in the chain.
if (SymbolicOffsetBase)

Просмотреть файл

@ -1029,7 +1029,7 @@ std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){
}
// Check if the parameter is a pointer to the symbol.
if (const loc::MemRegionVal *Reg = dyn_cast<loc::MemRegionVal>(&SV)) {
if (llvm::Optional<loc::MemRegionVal> Reg = SV.getAs<loc::MemRegionVal>()) {
SVal PSV = State->getSVal(Reg->getRegion());
SymbolRef AS = PSV.getAsLocSymbol();
if (AS == Sym) {

Просмотреть файл

@ -132,7 +132,7 @@ ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const
ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
ProgramStateManager &Mgr = getStateManager();
const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
ProgramStateRef new_state = makeWithStore(newStore);
return Mgr.getOwningEngine() ?
@ -189,7 +189,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
}
ProgramStateRef ProgramState::killBinding(Loc LV) const {
assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
assert(!LV.getAs<loc::MemRegionVal>() && "Use invalidateRegion instead.");
Store OldStore = getStore();
const StoreRef &newStore =
@ -253,7 +253,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
// not unsigned.
const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
if (isa<Loc>(V))
if (V.getAs<Loc>())
return loc::ConcreteInt(NewV);
else
return nonloc::ConcreteInt(NewV);
@ -301,28 +301,27 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
// Adjust the index.
SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
cast<NonLoc>(Idx), Min, indexTy);
Idx.castAs<NonLoc>(), Min, indexTy);
if (newIdx.isUnknownOrUndef())
return this;
// Adjust the upper bound.
SVal newBound =
svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound),
svalBuilder.evalBinOpNN(this, BO_Add, UpperBound.castAs<NonLoc>(),
Min, indexTy);
if (newBound.isUnknownOrUndef())
return this;
// Build the actual comparison.
SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT,
cast<NonLoc>(newIdx), cast<NonLoc>(newBound),
Ctx.IntTy);
SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
newBound.castAs<NonLoc>(), Ctx.IntTy);
if (inBound.isUnknownOrUndef())
return this;
// Finally, let the constraint manager take care of it.
ConstraintManager &CM = SM.getConstraintManager();
return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
}
ProgramStateRef ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
@ -509,10 +508,11 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) {
}
bool ScanReachableSymbols::scan(SVal val) {
if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
if (llvm::Optional<loc::MemRegionVal> X = val.getAs<loc::MemRegionVal>())
return scan(X->getRegion());
if (nonloc::LazyCompoundVal *X = dyn_cast<nonloc::LazyCompoundVal>(&val)) {
if (llvm::Optional<nonloc::LazyCompoundVal> X =
val.getAs<nonloc::LazyCompoundVal>()) {
StoreManager &StoreMgr = state->getStateManager().getStoreManager();
// FIXME: We don't really want to use getBaseRegion() here because pointer
// arithmetic doesn't apply, but scanReachableSymbols only accepts base
@ -523,7 +523,8 @@ bool ScanReachableSymbols::scan(SVal val) {
return false;
}
if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
if (llvm::Optional<nonloc::LocAsInteger> X =
val.getAs<nonloc::LocAsInteger>())
return scan(X->getLoc());
if (SymbolRef Sym = val.getAsSymbol())
@ -532,7 +533,7 @@ bool ScanReachableSymbols::scan(SVal val) {
if (const SymExpr *Sym = val.getAsSymbolicExpression())
return scan(Sym);
if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
if (llvm::Optional<nonloc::CompoundVal> X = val.getAs<nonloc::CompoundVal>())
return scan(*X);
return true;

Просмотреть файл

@ -753,7 +753,8 @@ static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
// be using this function anyway.
uint64_t Length = UINT64_MAX;
SVal Extent = Top->getExtent(SVB);
if (nonloc::ConcreteInt *ExtentCI = dyn_cast<nonloc::ConcreteInt>(&Extent)) {
if (llvm::Optional<nonloc::ConcreteInt> ExtentCI =
Extent.getAs<nonloc::ConcreteInt>()) {
const llvm::APSInt &ExtentInt = ExtentCI->getValue();
assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
// Extents are in bytes but region offsets are in bits. Be careful!
@ -893,8 +894,8 @@ void invalidateRegionsWorker::VisitBinding(SVal V) {
}
// Is it a LazyCompoundVal? All references get invalidated as well.
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
if (llvm::Optional<nonloc::LazyCompoundVal> LCS =
V.getAs<nonloc::LazyCompoundVal>()) {
const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
@ -938,7 +939,7 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
// a pointer value, but the thing pointed by that pointer may
// get invalidated.
SVal V = RM.getBinding(B, loc::MemRegionVal(VR));
if (const Loc *L = dyn_cast<Loc>(&V)) {
if (llvm::Optional<Loc> L = V.getAs<Loc>()) {
if (const MemRegion *LR = L->getAsRegion())
AddToWorkList(LR);
}
@ -1111,10 +1112,10 @@ RegionStoreManager::getSizeInElements(ProgramStateRef state,
/// the array). This is called by ExprEngine when evaluating casts
/// from arrays to pointers.
SVal RegionStoreManager::ArrayToPointer(Loc Array) {
if (!isa<loc::MemRegionVal>(Array))
if (!Array.getAs<loc::MemRegionVal>())
return UnknownVal();
const MemRegion* R = cast<loc::MemRegionVal>(&Array)->getRegion();
const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
const TypedValueRegion* ArrayR = dyn_cast<TypedValueRegion>(R);
if (!ArrayR)
@ -1134,8 +1135,8 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
//===----------------------------------------------------------------------===//
SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");
assert(!L.getAs<UnknownVal>() && "location unknown");
assert(!L.getAs<UndefinedVal>() && "location undefined");
// For access to concrete addresses, return UnknownVal. Checks
// for null dereferences (and similar errors) are done by checkers, not
@ -1143,14 +1144,14 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
// FIXME: We can consider lazily symbolicating such memory, but we really
// should defer this when we can reason easily about symbolicating arrays
// of bytes.
if (isa<loc::ConcreteInt>(L)) {
if (L.getAs<loc::ConcreteInt>()) {
return UnknownVal();
}
if (!isa<loc::MemRegionVal>(L)) {
if (!L.getAs<loc::MemRegionVal>()) {
return UnknownVal();
}
const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
const MemRegion *MR = L.castAs<loc::MemRegionVal>().getRegion();
if (isa<AllocaRegion>(MR) ||
isa<SymbolicRegion>(MR) ||
@ -1263,8 +1264,8 @@ RegionStoreManager::getLazyBinding(RegionBindingsConstRef B,
if (originalRegion != R) {
if (Optional<SVal> OV = B.getDefaultBinding(R)) {
if (const nonloc::LazyCompoundVal *V =
dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer()))
if (llvm::Optional<nonloc::LazyCompoundVal> V =
OV.getPointer()->getAs<nonloc::LazyCompoundVal>())
return std::make_pair(V->getStore(), V->getRegion());
}
}
@ -1345,7 +1346,8 @@ SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
const StringLiteral *Str = StrR->getStringLiteral();
SVal Idx = R->getIndex();
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
if (llvm::Optional<nonloc::ConcreteInt> CI =
Idx.getAs<nonloc::ConcreteInt>()) {
int64_t i = CI->getValue().getSExtValue();
// Abort on string underrun. This can be possible by arbitrary
// clients of getBindingForElement().
@ -1431,7 +1433,7 @@ RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
return val;
// Lazy bindings are handled later.
if (isa<nonloc::LazyCompoundVal>(val))
if (val.getAs<nonloc::LazyCompoundVal>())
return Optional<SVal>();
llvm_unreachable("Unknown default value");
@ -1650,9 +1652,8 @@ RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
if (V.isUnknownOrUndef() || V.isConstant())
continue;
const nonloc::LazyCompoundVal *InnerLCV =
dyn_cast<nonloc::LazyCompoundVal>(&V);
if (InnerLCV) {
if (llvm::Optional<nonloc::LazyCompoundVal> InnerLCV =
V.getAs<nonloc::LazyCompoundVal>()) {
const SValListTy &InnerList = getInterestingValues(*InnerLCV);
List.insert(List.end(), InnerList.begin(), InnerList.end());
continue;
@ -1669,9 +1670,8 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
// If we already have a lazy binding, and it's for the whole structure,
// don't create a new lazy binding.
if (Optional<SVal> V = B.getDefaultBinding(R)) {
const nonloc::LazyCompoundVal *LCV =
dyn_cast<nonloc::LazyCompoundVal>(V.getPointer());
if (LCV) {
if (llvm::Optional<nonloc::LazyCompoundVal> LCV =
V.getPointer()->getAs<nonloc::LazyCompoundVal>()) {
QualType RegionTy = R->getValueType();
QualType SourceRegionTy = LCV->getRegion()->getValueType();
if (Ctx.hasSameUnqualifiedType(RegionTy, SourceRegionTy))
@ -1728,8 +1728,8 @@ bool RegionStoreManager::includedInBindings(Store store,
//===----------------------------------------------------------------------===//
StoreRef RegionStoreManager::killBinding(Store ST, Loc L) {
if (isa<loc::MemRegionVal>(L))
if (const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion())
if (llvm::Optional<loc::MemRegionVal> LV = L.getAs<loc::MemRegionVal>())
if (const MemRegion* R = LV->getRegion())
return StoreRef(getRegionBindings(ST).removeBinding(R)
.asImmutableMap()
.getRootWithoutRetain(),
@ -1740,11 +1740,11 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) {
RegionBindingsRef
RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
if (isa<loc::ConcreteInt>(L))
if (L.getAs<loc::ConcreteInt>())
return B;
// If we get here, the location should be a region.
const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion();
const MemRegion *R = L.castAs<loc::MemRegionVal>().getRegion();
// Check if the region is a struct region.
if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {
@ -1820,18 +1820,18 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
Size = CAT->getSize().getZExtValue();
// Check if the init expr is a string literal.
if (loc::MemRegionVal *MRV = dyn_cast<loc::MemRegionVal>(&Init)) {
if (llvm::Optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) {
const StringRegion *S = cast<StringRegion>(MRV->getRegion());
// Treat the string as a lazy compound value.
StoreRef store(B.asStore(), *this);
nonloc::LazyCompoundVal LCV =
cast<nonloc::LazyCompoundVal>(svalBuilder.makeLazyCompoundVal(store, S));
nonloc::LazyCompoundVal LCV = svalBuilder.makeLazyCompoundVal(store, S)
.castAs<nonloc::LazyCompoundVal>();
return bindAggregate(B, R, LCV);
}
// Handle lazy compound values.
if (isa<nonloc::LazyCompoundVal>(Init))
if (Init.getAs<nonloc::LazyCompoundVal>())
return bindAggregate(B, R, Init);
// Remaining case: explicit compound values.
@ -1839,7 +1839,7 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
if (Init.isUnknown())
return setImplicitDefaultValue(B, R, ElementTy);
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>();
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
uint64_t i = 0;
@ -1877,18 +1877,18 @@ RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
const VectorType *VT = T->getAs<VectorType>(); // Use getAs for typedefs.
// Handle lazy compound values and symbolic values.
if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
return bindAggregate(B, R, V);
// We may get non-CompoundVal accidentally due to imprecise cast logic or
// that we are binding symbolic struct value. Kill the field values, and if
// the value is symbolic go and bind it as a "default" binding.
if (!isa<nonloc::CompoundVal>(V)) {
if (!V.getAs<nonloc::CompoundVal>()) {
return bindAggregate(B, R, UnknownVal());
}
QualType ElemType = VT->getElementType();
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
nonloc::CompoundVal CV = V.castAs<nonloc::CompoundVal>();
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
unsigned index = 0, numElements = VT->getNumElements();
RegionBindingsRef NewB(B);
@ -1926,16 +1926,16 @@ RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
return B;
// Handle lazy compound values and symbolic values.
if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
return bindAggregate(B, R, V);
// We may get non-CompoundVal accidentally due to imprecise cast logic or
// that we are binding symbolic struct value. Kill the field values, and if
// the value is symbolic go and bind it as a "default" binding.
if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
if (V.isUnknown() || !V.getAs<nonloc::CompoundVal>())
return bindAggregate(B, R, UnknownVal());
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
const nonloc::CompoundVal& CV = V.castAs<nonloc::CompoundVal>();
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
RecordDecl::field_iterator FI, FE;
@ -2057,8 +2057,8 @@ void removeDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
void removeDeadBindingsWorker::VisitBinding(SVal V) {
// Is it a LazyCompoundVal? All referenced regions are live as well.
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
if (llvm::Optional<nonloc::LazyCompoundVal> LCS =
V.getAs<nonloc::LazyCompoundVal>()) {
const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);

Просмотреть файл

@ -78,13 +78,14 @@ SVal SValBuilder::convertToArrayIndex(SVal val) {
return val;
// Common case: we have an appropriately sized integer.
if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&val)) {
if (llvm::Optional<nonloc::ConcreteInt> CI =
val.getAs<nonloc::ConcreteInt>()) {
const llvm::APSInt& I = CI->getValue();
if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
return val;
}
return evalCastFromNonLoc(cast<NonLoc>(val), ArrayIndexTy);
return evalCastFromNonLoc(val.castAs<NonLoc>(), ArrayIndexTy);
}
nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){
@ -237,11 +238,13 @@ SVal SValBuilder::makeSymExprValNN(ProgramStateRef State,
return makeNonLoc(symLHS, Op, symRHS, ResultTy);
if (symLHS && symLHS->computeComplexity() < MaxComp)
if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS))
if (llvm::Optional<nonloc::ConcreteInt> rInt =
RHS.getAs<nonloc::ConcreteInt>())
return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
if (symRHS && symRHS->computeComplexity() < MaxComp)
if (const nonloc::ConcreteInt *lInt = dyn_cast<nonloc::ConcreteInt>(&LHS))
if (llvm::Optional<nonloc::ConcreteInt> lInt =
LHS.getAs<nonloc::ConcreteInt>())
return makeNonLoc(lInt->getValue(), Op, symRHS, ResultTy);
return UnknownVal();
@ -257,30 +260,31 @@ SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
if (lhs.isUnknown() || rhs.isUnknown())
return UnknownVal();
if (isa<Loc>(lhs)) {
if (isa<Loc>(rhs))
return evalBinOpLL(state, op, cast<Loc>(lhs), cast<Loc>(rhs), type);
if (llvm::Optional<Loc> LV = lhs.getAs<Loc>()) {
if (llvm::Optional<Loc> RV = rhs.getAs<Loc>())
return evalBinOpLL(state, op, *LV, *RV, type);
return evalBinOpLN(state, op, cast<Loc>(lhs), cast<NonLoc>(rhs), type);
return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
}
if (isa<Loc>(rhs)) {
if (llvm::Optional<Loc> RV = rhs.getAs<Loc>()) {
// Support pointer arithmetic where the addend is on the left
// and the pointer on the right.
assert(op == BO_Add);
// Commute the operands.
return evalBinOpLN(state, op, cast<Loc>(rhs), cast<NonLoc>(lhs), type);
return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
}
return evalBinOpNN(state, op, cast<NonLoc>(lhs), cast<NonLoc>(rhs), type);
return evalBinOpNN(state, op, lhs.castAs<NonLoc>(), rhs.castAs<NonLoc>(),
type);
}
DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
DefinedOrUnknownSVal lhs,
DefinedOrUnknownSVal rhs) {
return cast<DefinedOrUnknownSVal>(evalBinOp(state, BO_EQ, lhs, rhs,
Context.IntTy));
return evalBinOp(state, BO_EQ, lhs, rhs, Context.IntTy)
.castAs<DefinedOrUnknownSVal>();
}
/// Recursively check if the pointer types are equal modulo const, volatile,
@ -327,11 +331,12 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
// Check for casts from pointers to integers.
if (castTy->isIntegerType() && Loc::isLocType(originalTy))
return evalCastFromLoc(cast<Loc>(val), castTy);
return evalCastFromLoc(val.castAs<Loc>(), castTy);
// Check for casts from integers to pointers.
if (Loc::isLocType(castTy) && originalTy->isIntegerType()) {
if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
if (llvm::Optional<nonloc::LocAsInteger> LV =
val.getAs<nonloc::LocAsInteger>()) {
if (const MemRegion *R = LV->getLoc().getAsRegion()) {
StoreManager &storeMgr = StateMgr.getStoreManager();
R = storeMgr.castRegion(R, castTy);
@ -351,7 +356,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
// Check for casts from array type to another type.
if (originalTy->isArrayType()) {
// We will always decay to a pointer.
val = StateMgr.ArrayToPointer(cast<Loc>(val));
val = StateMgr.ArrayToPointer(val.castAs<Loc>());
// Are we casting from an array to a pointer? If so just pass on
// the decayed value.
@ -366,7 +371,7 @@ SVal SValBuilder::evalCast(SVal val, QualType castTy, QualType originalTy) {
// need the original decayed type.
// QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
// QualType pointerTy = C.getPointerType(elemTy);
return evalCastFromLoc(cast<Loc>(val), castTy);
return evalCastFromLoc(val.castAs<Loc>(), castTy);
}
// Check for casts from a region to a specific type.

Просмотреть файл

@ -30,13 +30,13 @@ using llvm::APSInt;
//===----------------------------------------------------------------------===//
bool SVal::hasConjuredSymbol() const {
if (const nonloc::SymbolVal* SV = dyn_cast<nonloc::SymbolVal>(this)) {
if (llvm::Optional<nonloc::SymbolVal> SV = getAs<nonloc::SymbolVal>()) {
SymbolRef sym = SV->getSymbol();
if (isa<SymbolConjured>(sym))
return true;
}
if (const loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(this)) {
if (llvm::Optional<loc::MemRegionVal> RV = getAs<loc::MemRegionVal>()) {
const MemRegion *R = RV->getRegion();
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
SymbolRef sym = SR->getSymbol();
@ -49,7 +49,7 @@ bool SVal::hasConjuredSymbol() const {
}
const FunctionDecl *SVal::getAsFunctionDecl() const {
if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
const MemRegion* R = X->getRegion();
if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CTR->getDecl()))
@ -66,10 +66,10 @@ const FunctionDecl *SVal::getAsFunctionDecl() const {
/// region. If that is the case, gets the underlining region.
SymbolRef SVal::getAsLocSymbol() const {
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this))
if (llvm::Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
return X->getLoc().getAsLocSymbol();
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
const MemRegion *R = X->stripCasts();
if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
return SymR->getSymbol();
@ -79,7 +79,7 @@ SymbolRef SVal::getAsLocSymbol() const {
/// Get the symbol in the SVal or its base region.
SymbolRef SVal::getLocSymbolInBase() const {
const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>();
if (!X)
return 0;
@ -102,7 +102,7 @@ SymbolRef SVal::getLocSymbolInBase() const {
/// Otherwise return 0.
SymbolRef SVal::getAsSymbol() const {
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
if (llvm::Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
return X->getSymbol();
return getAsLocSymbol();
@ -111,7 +111,7 @@ SymbolRef SVal::getAsSymbol() const {
/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
/// return that expression. Otherwise return NULL.
const SymExpr *SVal::getAsSymbolicExpression() const {
if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
if (llvm::Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
return X->getSymbol();
return getAsSymbol();
@ -125,12 +125,11 @@ const SymExpr* SVal::getAsSymExpr() const {
}
const MemRegion *SVal::getAsRegion() const {
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
if (llvm::Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>())
return X->getRegion();
if (const nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(this)) {
if (llvm::Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
return X->getLoc().getAsRegion();
}
return 0;
}
@ -165,16 +164,15 @@ nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
//===----------------------------------------------------------------------===//
bool SVal::isConstant() const {
return isa<nonloc::ConcreteInt>(this) || isa<loc::ConcreteInt>(this);
return getAs<nonloc::ConcreteInt>() || getAs<loc::ConcreteInt>();
}
bool SVal::isConstant(int I) const {
if (isa<loc::ConcreteInt>(*this))
return cast<loc::ConcreteInt>(*this).getValue() == I;
else if (isa<nonloc::ConcreteInt>(*this))
return cast<nonloc::ConcreteInt>(*this).getValue() == I;
else
return false;
if (llvm::Optional<loc::ConcreteInt> LV = getAs<loc::ConcreteInt>())
return LV->getValue() == I;
if (llvm::Optional<nonloc::ConcreteInt> NV = getAs<nonloc::ConcreteInt>())
return NV->getValue() == I;
return false;
}
bool SVal::isZeroConstant() const {
@ -239,10 +237,10 @@ void SVal::dumpToStream(raw_ostream &os) const {
os << "Unknown";
break;
case NonLocKind:
cast<NonLoc>(this)->dumpToStream(os);
castAs<NonLoc>().dumpToStream(os);
break;
case LocKind:
cast<Loc>(this)->dumpToStream(os);
castAs<Loc>().dumpToStream(os);
break;
case UndefinedKind:
os << "Undefined";
@ -253,7 +251,7 @@ void SVal::dumpToStream(raw_ostream &os) const {
void NonLoc::dumpToStream(raw_ostream &os) const {
switch (getSubKind()) {
case nonloc::ConcreteIntKind: {
const nonloc::ConcreteInt& C = *cast<nonloc::ConcreteInt>(this);
const nonloc::ConcreteInt& C = castAs<nonloc::ConcreteInt>();
if (C.getValue().isUnsigned())
os << C.getValue().getZExtValue();
else
@ -263,16 +261,16 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
break;
}
case nonloc::SymbolValKind: {
os << cast<nonloc::SymbolVal>(this)->getSymbol();
os << castAs<nonloc::SymbolVal>().getSymbol();
break;
}
case nonloc::LocAsIntegerKind: {
const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
const nonloc::LocAsInteger& C = castAs<nonloc::LocAsInteger>();
os << C.getLoc() << " [as " << C.getNumBits() << " bit integer]";
break;
}
case nonloc::CompoundValKind: {
const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
const nonloc::CompoundVal& C = castAs<nonloc::CompoundVal>();
os << "compoundVal{";
bool first = true;
for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
@ -288,7 +286,7 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
break;
}
case nonloc::LazyCompoundValKind: {
const nonloc::LazyCompoundVal &C = *cast<nonloc::LazyCompoundVal>(this);
const nonloc::LazyCompoundVal &C = castAs<nonloc::LazyCompoundVal>();
os << "lazyCompoundVal{" << const_cast<void *>(C.getStore())
<< ',' << C.getRegion()
<< '}';
@ -303,13 +301,13 @@ void NonLoc::dumpToStream(raw_ostream &os) const {
void Loc::dumpToStream(raw_ostream &os) const {
switch (getSubKind()) {
case loc::ConcreteIntKind:
os << cast<loc::ConcreteInt>(this)->getValue().getZExtValue() << " (Loc)";
os << castAs<loc::ConcreteInt>().getValue().getZExtValue() << " (Loc)";
break;
case loc::GotoLabelKind:
os << "&&" << cast<loc::GotoLabel>(this)->getLabel()->getName();
os << "&&" << castAs<loc::GotoLabel>().getLabel()->getName();
break;
case loc::MemRegionKind:
os << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
os << '&' << castAs<loc::MemRegionVal>().getRegion()->getString();
break;
default:
llvm_unreachable("Pretty-printing not implemented for this Loc.");

Просмотреть файл

@ -24,7 +24,7 @@ namespace ento {
SimpleConstraintManager::~SimpleConstraintManager() {}
bool SimpleConstraintManager::canReasonAbout(SVal X) const {
nonloc::SymbolVal *SymVal = dyn_cast<nonloc::SymbolVal>(&X);
llvm::Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
if (SymVal && SymVal->isExpression()) {
const SymExpr *SE = SymVal->getSymbol();
@ -58,10 +58,9 @@ bool SimpleConstraintManager::canReasonAbout(SVal X) const {
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state,
DefinedSVal Cond,
bool Assumption) {
if (isa<NonLoc>(Cond))
return assume(state, cast<NonLoc>(Cond), Assumption);
else
return assume(state, cast<Loc>(Cond), Assumption);
if (llvm::Optional<NonLoc> NV = Cond.getAs<NonLoc>())
return assume(state, *NV, Assumption);
return assume(state, Cond.castAs<Loc>(), Assumption);
}
ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef state, Loc cond,
@ -82,7 +81,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
case loc::MemRegionKind: {
// FIXME: Should this go into the storemanager?
const MemRegion *R = cast<loc::MemRegionVal>(Cond).getRegion();
const MemRegion *R = Cond.castAs<loc::MemRegionVal>().getRegion();
const SubRegion *SubR = dyn_cast<SubRegion>(R);
while (SubR) {
@ -104,7 +103,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
return Assumption ? state : NULL;
case loc::ConcreteIntKind: {
bool b = cast<loc::ConcreteInt>(Cond).getValue() != 0;
bool b = Cond.castAs<loc::ConcreteInt>().getValue() != 0;
bool isFeasible = b ? Assumption : !Assumption;
return isFeasible ? state : NULL;
}
@ -172,7 +171,7 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
llvm_unreachable("'Assume' not implemented for this NonLoc");
case nonloc::SymbolValKind: {
nonloc::SymbolVal& SV = cast<nonloc::SymbolVal>(Cond);
nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
SymbolRef sym = SV.getSymbol();
assert(sym);
@ -204,13 +203,13 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef state,
}
case nonloc::ConcreteIntKind: {
bool b = cast<nonloc::ConcreteInt>(Cond).getValue() != 0;
bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
bool isFeasible = b ? Assumption : !Assumption;
return isFeasible ? state : NULL;
}
case nonloc::LocAsIntegerKind:
return assumeAux(state, cast<nonloc::LocAsInteger>(Cond).getLoc(),
return assumeAux(state, Cond.castAs<nonloc::LocAsInteger>().getLoc(),
Assumption);
} // end switch
}

Просмотреть файл

@ -60,16 +60,17 @@ SValBuilder *ento::createSimpleSValBuilder(llvm::BumpPtrAllocator &alloc,
//===----------------------------------------------------------------------===//
SVal SimpleSValBuilder::dispatchCast(SVal Val, QualType CastTy) {
assert(isa<Loc>(&Val) || isa<NonLoc>(&Val));
return isa<Loc>(Val) ? evalCastFromLoc(cast<Loc>(Val), CastTy)
: evalCastFromNonLoc(cast<NonLoc>(Val), CastTy);
assert(Val.getAs<Loc>() || Val.getAs<NonLoc>());
return Val.getAs<Loc>() ? evalCastFromLoc(Val.castAs<Loc>(), CastTy)
: evalCastFromNonLoc(Val.castAs<NonLoc>(), CastTy);
}
SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
bool isLocType = Loc::isLocType(castTy);
if (nonloc::LocAsInteger *LI = dyn_cast<nonloc::LocAsInteger>(&val)) {
if (llvm::Optional<nonloc::LocAsInteger> LI =
val.getAs<nonloc::LocAsInteger>()) {
if (isLocType)
return LI->getLoc();
@ -98,12 +99,12 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
}
// If value is a non integer constant, produce unknown.
if (!isa<nonloc::ConcreteInt>(val))
if (!val.getAs<nonloc::ConcreteInt>())
return UnknownVal();
// Handle casts to a boolean type.
if (castTy->isBooleanType()) {
bool b = cast<nonloc::ConcreteInt>(val).getValue().getBoolValue();
bool b = val.castAs<nonloc::ConcreteInt>().getValue().getBoolValue();
return makeTruthVal(b, castTy);
}
@ -112,7 +113,7 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
if (!isLocType && !castTy->isIntegerType())
return UnknownVal();
llvm::APSInt i = cast<nonloc::ConcreteInt>(val).getValue();
llvm::APSInt i = val.castAs<nonloc::ConcreteInt>().getValue();
BasicVals.getAPSIntType(castTy).apply(i);
if (isLocType)
@ -140,10 +141,10 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
if (castTy->isIntegerType()) {
unsigned BitWidth = Context.getTypeSize(castTy);
if (!isa<loc::ConcreteInt>(val))
if (!val.getAs<loc::ConcreteInt>())
return makeLocAsInteger(val, BitWidth);
llvm::APSInt i = cast<loc::ConcreteInt>(val).getValue();
llvm::APSInt i = val.castAs<loc::ConcreteInt>().getValue();
BasicVals.getAPSIntType(castTy).apply(i);
return makeIntVal(i);
}
@ -161,7 +162,7 @@ SVal SimpleSValBuilder::evalCastFromLoc(Loc val, QualType castTy) {
SVal SimpleSValBuilder::evalMinus(NonLoc val) {
switch (val.getSubKind()) {
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(val).evalMinus(*this);
return val.castAs<nonloc::ConcreteInt>().evalMinus(*this);
default:
return UnknownVal();
}
@ -170,7 +171,7 @@ SVal SimpleSValBuilder::evalMinus(NonLoc val) {
SVal SimpleSValBuilder::evalComplement(NonLoc X) {
switch (X.getSubKind()) {
case nonloc::ConcreteIntKind:
return cast<nonloc::ConcreteInt>(X).evalComplement(*this);
return X.castAs<nonloc::ConcreteInt>().evalComplement(*this);
default:
return UnknownVal();
}
@ -337,15 +338,15 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
default:
return makeSymExprValNN(state, op, lhs, rhs, resultTy);
case nonloc::LocAsIntegerKind: {
Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
switch (rhs.getSubKind()) {
case nonloc::LocAsIntegerKind:
return evalBinOpLL(state, op, lhsL,
cast<nonloc::LocAsInteger>(rhs).getLoc(),
rhs.castAs<nonloc::LocAsInteger>().getLoc(),
resultTy);
case nonloc::ConcreteIntKind: {
// Transform the integer into a location and compare.
llvm::APSInt i = cast<nonloc::ConcreteInt>(rhs).getValue();
llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue();
BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
}
@ -362,7 +363,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
}
}
case nonloc::ConcreteIntKind: {
llvm::APSInt LHSValue = cast<nonloc::ConcreteInt>(lhs).getValue();
llvm::APSInt LHSValue = lhs.castAs<nonloc::ConcreteInt>().getValue();
// If we're dealing with two known constants, just perform the operation.
if (const llvm::APSInt *KnownRHSValue = getKnownValue(state, rhs)) {
@ -425,7 +426,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
}
case nonloc::SymbolValKind: {
// We only handle LHS as simple symbols or SymIntExprs.
SymbolRef Sym = cast<nonloc::SymbolVal>(lhs).getSymbol();
SymbolRef Sym = lhs.castAs<nonloc::SymbolVal>().getSymbol();
// LHS is a symbolic expression.
if (const SymIntExpr *symIntExpr = dyn_cast<SymIntExpr>(Sym)) {
@ -601,15 +602,15 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
if (!BinaryOperator::isComparisonOp(op))
return UnknownVal();
const llvm::APSInt &lVal = cast<loc::ConcreteInt>(lhs).getValue();
const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
return makeNonLoc(rSym, ReverseComparison(op), lVal, resultTy);
}
// If both operands are constants, just perform the operation.
if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
SVal ResultVal = cast<loc::ConcreteInt>(lhs).evalBinOp(BasicVals, op,
*rInt);
if (Loc *Result = dyn_cast<Loc>(&ResultVal))
if (llvm::Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
SVal ResultVal =
lhs.castAs<loc::ConcreteInt>().evalBinOp(BasicVals, op, *rInt);
if (llvm::Optional<Loc> Result = ResultVal.getAs<Loc>())
return evalCastFromLoc(*Result, resultTy);
else
return UnknownVal();
@ -619,7 +620,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
// This must come after the test if the RHS is a symbol, which is used to
// build constraints. The address of any non-symbolic region is guaranteed
// to be non-NULL, as is any label.
assert(isa<loc::MemRegionVal>(rhs) || isa<loc::GotoLabel>(rhs));
assert(rhs.getAs<loc::MemRegionVal>() || rhs.getAs<loc::GotoLabel>());
if (lhs.isZeroConstant()) {
switch (op) {
default:
@ -640,7 +641,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
return UnknownVal();
}
case loc::MemRegionKind: {
if (loc::ConcreteInt *rInt = dyn_cast<loc::ConcreteInt>(&rhs)) {
if (llvm::Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
// If one of the operands is a symbol and the other is a constant,
// build an expression for use by the constraint manager.
if (SymbolRef lSym = lhs.getAsLocSymbol())
@ -738,21 +739,21 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
// Get the left index and cast it to the correct type.
// If the index is unknown or undefined, bail out here.
SVal LeftIndexVal = LeftER->getIndex();
NonLoc *LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
llvm::Optional<NonLoc> LeftIndex = LeftIndexVal.getAs<NonLoc>();
if (!LeftIndex)
return UnknownVal();
LeftIndexVal = evalCastFromNonLoc(*LeftIndex, ArrayIndexTy);
LeftIndex = dyn_cast<NonLoc>(&LeftIndexVal);
LeftIndex = LeftIndexVal.getAs<NonLoc>();
if (!LeftIndex)
return UnknownVal();
// Do the same for the right index.
SVal RightIndexVal = RightER->getIndex();
NonLoc *RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
llvm::Optional<NonLoc> RightIndex = RightIndexVal.getAs<NonLoc>();
if (!RightIndex)
return UnknownVal();
RightIndexVal = evalCastFromNonLoc(*RightIndex, ArrayIndexTy);
RightIndex = dyn_cast<NonLoc>(&RightIndexVal);
RightIndex = RightIndexVal.getAs<NonLoc>();
if (!RightIndex)
return UnknownVal();
@ -862,7 +863,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// can generate comparisons that trigger this code.
// FIXME: Are all locations guaranteed to have pointer width?
if (BinaryOperator::isComparisonOp(op)) {
if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
if (llvm::Optional<nonloc::ConcreteInt> rhsInt =
rhs.getAs<nonloc::ConcreteInt>()) {
const llvm::APSInt *x = &rhsInt->getValue();
ASTContext &ctx = Context;
if (ctx.getTypeSize(ctx.VoidPtrTy) == x->getBitWidth()) {
@ -879,8 +881,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// We are dealing with pointer arithmetic.
// Handle pointer arithmetic on constant values.
if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
if (loc::ConcreteInt *lhsInt = dyn_cast<loc::ConcreteInt>(&lhs)) {
if (llvm::Optional<nonloc::ConcreteInt> rhsInt =
rhs.getAs<nonloc::ConcreteInt>()) {
if (llvm::Optional<loc::ConcreteInt> lhsInt =
lhs.getAs<loc::ConcreteInt>()) {
const llvm::APSInt &leftI = lhsInt->getValue();
assert(leftI.isUnsigned());
llvm::APSInt rightI(rhsInt->getValue(), /* isUnsigned */ true);
@ -910,7 +914,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// Handle cases where 'lhs' is a region.
if (const MemRegion *region = lhs.getAsRegion()) {
rhs = cast<NonLoc>(convertToArrayIndex(rhs));
rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
SVal index = UnknownVal();
const MemRegion *superR = 0;
QualType elementType;
@ -929,7 +933,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
elementType = resultTy->getPointeeType();
}
if (NonLoc *indexV = dyn_cast<NonLoc>(&index)) {
if (llvm::Optional<NonLoc> indexV = index.getAs<NonLoc>()) {
return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV,
superR, getContext()));
}
@ -942,10 +946,10 @@ const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
if (V.isUnknownOrUndef())
return NULL;
if (loc::ConcreteInt* X = dyn_cast<loc::ConcreteInt>(&V))
if (llvm::Optional<loc::ConcreteInt> X = V.getAs<loc::ConcreteInt>())
return &X->getValue();
if (nonloc::ConcreteInt* X = dyn_cast<nonloc::ConcreteInt>(&V))
if (llvm::Optional<nonloc::ConcreteInt> X = V.getAs<nonloc::ConcreteInt>())
return &X->getValue();
if (SymbolRef Sym = V.getAsSymbol())

Просмотреть файл

@ -270,7 +270,8 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
}
SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType) {
loc::MemRegionVal *DerivedRegVal = dyn_cast<loc::MemRegionVal>(&Derived);
llvm::Optional<loc::MemRegionVal> DerivedRegVal =
Derived.getAs<loc::MemRegionVal>();
if (!DerivedRegVal)
return Derived;
@ -289,7 +290,8 @@ SVal StoreManager::evalDynamicCast(SVal Base, QualType DerivedType,
bool &Failed) {
Failed = false;
loc::MemRegionVal *BaseRegVal = dyn_cast<loc::MemRegionVal>(&Base);
llvm::Optional<loc::MemRegionVal> BaseRegVal =
Base.getAs<loc::MemRegionVal>();
if (!BaseRegVal)
return UnknownVal();
const MemRegion *BaseRegion = BaseRegVal->stripCasts(/*StripBases=*/false);
@ -373,12 +375,12 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
if (Base.isUnknownOrUndef())
return Base;
Loc BaseL = cast<Loc>(Base);
Loc BaseL = Base.castAs<Loc>();
const MemRegion* BaseR = 0;
switch (BaseL.getSubKind()) {
case loc::MemRegionKind:
BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
break;
case loc::GotoLabelKind:
@ -415,16 +417,16 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
// FIXME: For absolute pointer addresses, we just return that value back as
// well, although in reality we should return the offset added to that
// value.
if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
return Base;
const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
// Pointer of any type can be cast and used as array base.
const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
// Convert the offset to the appropriate size and signedness.
Offset = cast<NonLoc>(svalBuilder.convertToArrayIndex(Offset));
Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
if (!ElemR) {
//
@ -442,15 +444,16 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
SVal BaseIdx = ElemR->getIndex();
if (!isa<nonloc::ConcreteInt>(BaseIdx))
if (!BaseIdx.getAs<nonloc::ConcreteInt>())
return UnknownVal();
const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
const llvm::APSInt &BaseIdxI =
BaseIdx.castAs<nonloc::ConcreteInt>().getValue();
// Only allow non-integer offsets if the base region has no offset itself.
// FIXME: This is a somewhat arbitrary restriction. We should be using
// SValBuilder here to add the two offsets without checking their types.
if (!isa<nonloc::ConcreteInt>(Offset)) {
if (!Offset.getAs<nonloc::ConcreteInt>()) {
if (isa<ElementRegion>(BaseRegion->StripCasts()))
return UnknownVal();
@ -459,7 +462,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
Ctx));
}
const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
assert(BaseIdxI.isSigned());
// Compute the new index.