See r175462 for another example/more details.
llvm-svn: 175594
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:
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,
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");
}
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,
}
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();
}
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;
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;
}
};
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();
}
};
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;
}
};
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;
+ }
};
//==------------------------------------------------------------------------==//
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;
}
};
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 {
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;
}
};
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;
}
};
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;
}
};
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;
}
};
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;
}
};
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;
}
};
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,
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;
// 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;
// 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
// 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());
}
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.
offset = addValue(state,
getValue(offset, svalBuilder),
scaleValue(state,
- cast<NonLoc>(index),
+ index.castAs<NonLoc>(),
astContext.getTypeSizeInChars(elemType),
svalBuilder),
svalBuilder);
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);
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;
}
static inline bool isNil(SVal X) {
- return isa<loc::ConcreteInt>(X);
+ return X.getAs<loc::ConcreteInt>();
}
//===----------------------------------------------------------------------===//
// 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;
// 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;
// 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);
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.
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);
}
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;
}
// 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;
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.
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.
// 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);
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);
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());
// 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,
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,
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;
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;
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;
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;
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 {
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,
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.
// 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();
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
// 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());
// 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);
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.
// 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.
// 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.
// 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
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,
// 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 "
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;
}
*amountCopiedNL,
*strLengthNL,
cmpTy);
- state = state->assume(cast<DefinedOrUnknownSVal>(copiedLessThanSrc),
- true);
+ state = state->assume(
+ copiedLessThanSrc.castAs<DefinedOrUnknownSVal>(), true);
if (!state)
return;
}
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) {
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;
*finalStrLengthNL,
*dstStrLengthNL,
cmpTy);
- state = state->assume(cast<DefinedOrUnknownSVal>(destInResult),
- true);
+ state =
+ state->assume(destInResult.castAs<DefinedOrUnknownSVal>(), true);
if (!state)
return;
}
// 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,
}
// 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);
// 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();
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);
}
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:
}
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)
}
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)
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;
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();
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) {
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.
ProgramStateRef StTrue, StFalse;
llvm::tie(StTrue, StFalse) =
- State->assume(cast<DefinedOrUnknownSVal>(AssertionVal));
+ State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>());
if (StTrue) {
if (StFalse)
if (AddrVal.isUnknownOrUndef())
return 0;
- Loc *AddrLoc = dyn_cast<Loc>(&AddrVal);
+ llvm::Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
if (!AddrLoc)
return 0;
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());
}
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)
// 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)
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.
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);
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();
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.
}
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;
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();
// 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 =
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 *
CheckerContext &C) const {
if (!isLoad)
return;
- if (loc.isUndef() || !isa<Loc>(loc))
+ if (loc.isUndef() || !loc.getAs<Loc>())
return;
ASTContext &Ctx = C.getASTContext();
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;
}
}
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 "
// 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) {
if (!ArraySym)
return;
- C.addTransition(State->set<ArraySizeMap>(ArraySym, cast<DefinedSVal>(SizeV)));
+ C.addTransition(
+ State->set<ArraySizeMap>(ArraySym, SizeV.castAs<DefinedSVal>()));
return;
}
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();
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)) {
// 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
// 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);
}
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());
if (X.isUnknownOrUndef())
return;
- DefinedSVal retVal = cast<DefinedSVal>(X);
+ DefinedSVal retVal = X.castAs<DefinedSVal>();
if (state->contains<LockSet>(lockR)) {
if (!BT_doublelock)
// 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) {
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();
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;
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;
// 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;
ProgramStateRef *trueState,
ProgramStateRef *falseState) {
llvm::tie(*trueState, *falseState) =
- state->assume(cast<DefinedSVal>(argVal));
+ state->assume(argVal.castAs<DefinedSVal>());
return (*falseState && !*trueState);
}
}
// 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);
// 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);
// 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;
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.
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);
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))
// 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);
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)) {
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()) {
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";
}
}
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)) {
}
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 ";
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");
}
// 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);
}
// 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());
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);
// 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));
}
// 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()) {
return UnknownVal();
SVal ThisVal = getSVal(Base);
- assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
+ assert(ThisVal.isUnknownOrUndef() || ThisVal.getAs<Loc>());
return ThisVal;
}
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);
svalBuilder.makeZeroVal(T),
getContext().IntTy);
- DefinedOrUnknownSVal *Constraint =
- dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
+ llvm::Optional<DefinedOrUnknownSVal> Constraint =
+ Constraint_untested.getAs<DefinedOrUnknownSVal>();
if (!Constraint)
break;
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");
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");
}
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);
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,
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,
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);
}
continue;
}
- DefinedSVal V = cast<DefinedSVal>(X);
+ DefinedSVal V = X.castAs<DefinedSVal>();
ProgramStateRef StTrue, StFalse;
tie(StTrue, StFalse) = PrevState->assume(V);
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) {
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.
return;
}
- DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
+ DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
ProgramStateRef DefaultSt = state;
// 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;
}
// 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;
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) {
// 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);
// 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();
}
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
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,
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();
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);
// 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);
} 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
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) {
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)."
// 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());
}
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;
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);
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);
(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));
}
}
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.
// 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);
}
// 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);
}
// 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
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);
// 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();
}
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)
}
// 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) {
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() ?
}
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 =
// 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);
// 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) {
}
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
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())
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;
// 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!
}
// 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);
// 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);
}
/// 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)
//===----------------------------------------------------------------------===//
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
// 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) ||
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());
}
}
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().
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");
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;
// 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))
//===----------------------------------------------------------------------===//
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(),
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)) {
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.
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;
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);
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;
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);
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){
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();
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,
// 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);
// 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.
// 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.
//===----------------------------------------------------------------------===//
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();
}
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()))
/// 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();
/// 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;
/// 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();
/// 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();
}
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;
}
//===----------------------------------------------------------------------===//
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 {
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";
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
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) {
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()
<< '}';
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.");
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();
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,
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) {
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;
}
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);
}
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
}
//===----------------------------------------------------------------------===//
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();
}
// 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);
}
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)
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);
}
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();
}
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();
}
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);
}
}
}
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)) {
}
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)) {
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();
// 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:
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())
// 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();
// 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()) {
// 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);
// 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;
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()));
}
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())
}
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;
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);
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:
// 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) {
//
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();
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.