aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp46
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp59
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp30
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp27
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp76
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp39
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp54
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp72
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp25
17 files changed, 255 insertions, 237 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 17dd772a68..8afd4887cf 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -228,7 +228,7 @@ public:
// If we can't prove the return value is 0, just mark it interesting, and
// make sure to track it into any further inner functions.
- if (State->assume(cast<DefinedSVal>(V), true)) {
+ if (State->assume(V.castAs<DefinedSVal>(), true)) {
BR.markInteresting(V);
ReturnVisitor::addVisitorIfNecessary(N, RetE, BR);
return 0;
@@ -241,7 +241,7 @@ public:
SmallString<64> Msg;
llvm::raw_svector_ostream Out(Msg);
- if (isa<Loc>(V)) {
+ if (V.getAs<Loc>()) {
// If we are pruning null-return paths as unlikely error paths, mark the
// report invalid. We still want to emit a path note, however, in case
// the report is resurrected as valid later on.
@@ -298,7 +298,7 @@ public:
CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
SVal ArgV = Call->getArgSVal(I);
- if (!isa<Loc>(ArgV))
+ if (!ArgV.getAs<Loc>())
continue;
const Expr *ArgE = Call->getArgExpr(I);
@@ -306,7 +306,7 @@ public:
continue;
// Is it possible for this argument to be non-null?
- if (State->assume(cast<Loc>(ArgV), true))
+ if (State->assume(ArgV.castAs<Loc>(), true))
continue;
if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true))
@@ -415,7 +415,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
// If we have an expression that provided the value, try to track where it
// came from.
if (InitE) {
- if (V.isUndef() || isa<loc::ConcreteInt>(V)) {
+ if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
if (!IsParam)
InitE = InitE->IgnoreParenCasts();
bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam);
@@ -462,7 +462,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
os << "Variable '" << *VR->getDecl() << "' ";
- if (isa<loc::ConcreteInt>(V)) {
+ if (V.getAs<loc::ConcreteInt>()) {
bool b = false;
if (R->isBoundable()) {
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@@ -475,9 +475,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (!b)
os << action << "a null pointer value";
- }
- else if (isa<nonloc::ConcreteInt>(V)) {
- os << action << cast<nonloc::ConcreteInt>(V).getValue();
+ } else if (llvm::Optional<nonloc::ConcreteInt> CVal =
+ V.getAs<nonloc::ConcreteInt>()) {
+ os << action << CVal->getValue();
}
else if (DS) {
if (V.isUndef()) {
@@ -499,15 +499,16 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
os << "Passing ";
- if (isa<loc::ConcreteInt>(V)) {
+ if (V.getAs<loc::ConcreteInt>()) {
if (Param->getType()->isObjCObjectPointerType())
os << "nil object reference";
else
os << "null pointer value";
} else if (V.isUndef()) {
os << "uninitialized value";
- } else if (isa<nonloc::ConcreteInt>(V)) {
- os << "the value " << cast<nonloc::ConcreteInt>(V).getValue();
+ } else if (llvm::Optional<nonloc::ConcreteInt> CI =
+ V.getAs<nonloc::ConcreteInt>()) {
+ os << "the value " << CI->getValue();
} else {
os << "value";
}
@@ -521,7 +522,7 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
}
if (os.str().empty()) {
- if (isa<loc::ConcreteInt>(V)) {
+ if (V.getAs<loc::ConcreteInt>()) {
bool b = false;
if (R->isBoundable()) {
if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
@@ -537,10 +538,9 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
}
else if (V.isUndef()) {
os << "Uninitialized value stored to ";
- }
- else if (isa<nonloc::ConcreteInt>(V)) {
- os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
- << " is assigned to ";
+ } else if (llvm::Optional<nonloc::ConcreteInt> CV =
+ V.getAs<nonloc::ConcreteInt>()) {
+ os << "The value " << CV->getValue() << " is assigned to ";
}
else
os << "Value assigned to ";
@@ -601,7 +601,7 @@ TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
- if (isa<Loc>(Constraint)) {
+ if (Constraint.getAs<Loc>()) {
os << "Assuming pointer value is ";
os << (Assumption ? "non-null" : "null");
}
@@ -693,8 +693,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
// If the contents are symbolic, find out when they became null.
if (V.getAsLocSymbol()) {
- BugReporterVisitor *ConstraintTracker
- = new TrackConstraintBRVisitor(cast<DefinedSVal>(V), false);
+ BugReporterVisitor *ConstraintTracker =
+ new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
report.addVisitor(ConstraintTracker);
}
@@ -713,7 +713,7 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
// assert(!V.isUnknownOrUndef());
// Is it a symbolic value?
- if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
+ if (llvm::Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
// At this point we are dealing with the region's LValue.
// However, if the rvalue is a symbolic region, we should track it as well.
SVal RVal = state->getSVal(L->getRegion());
@@ -766,7 +766,7 @@ PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
return 0;
ProgramStateRef state = N->getState();
const SVal &V = state->getSVal(Receiver, N->getLocationContext());
- const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
+ llvm::Optional<DefinedOrUnknownSVal> DV = V.getAs<DefinedOrUnknownSVal>();
if (!DV)
return 0;
state = state->assume(*DV, true);
@@ -806,7 +806,7 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
// What did we load?
SVal V = state->getSVal(S, N->getLocationContext());
- if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
+ if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
// Register a new visitor with the BugReport.
BR.addVisitor(new FindLastStoreBRVisitor(V, R));
}
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index a75efc60b9..a09d483150 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -156,9 +156,10 @@ ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
// If we are passing a location wrapped as an integer, unwrap it and
// invalidate the values referred by the location.
- if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
+ if (llvm::Optional<nonloc::LocAsInteger> Wrapped =
+ V.getAs<nonloc::LocAsInteger>())
V = Wrapped->getLoc();
- else if (!isa<Loc>(V))
+ else if (!V.getAs<Loc>())
continue;
if (const MemRegion *R = V.getAsRegion()) {
@@ -419,7 +420,7 @@ SVal CXXInstanceCall::getCXXThisVal() const {
return UnknownVal();
SVal ThisVal = getSVal(Base);
- assert(ThisVal.isUnknownOrUndef() || isa<Loc>(ThisVal));
+ assert(ThisVal.isUnknownOrUndef() || ThisVal.getAs<Loc>());
return ThisVal;
}
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index 2b069a04a5..481e1bfd37 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -198,10 +198,8 @@ EnvironmentManager::removeDeadBindings(Environment Env,
EBMapRef = EBMapRef.add(BlkExpr, X);
// If the block expr's value is a memory region, then mark that region.
- if (isa<loc::MemRegionVal>(X)) {
- const MemRegion *R = cast<loc::MemRegionVal>(X).getRegion();
- SymReaper.markLive(R);
- }
+ if (llvm::Optional<loc::MemRegionVal> R = X.getAs<loc::MemRegionVal>())
+ SymReaper.markLive(R->getRegion());
// Mark all symbols in the block expr's value live.
RSScaner.scan(X);
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 18ac0964aa..a077056174 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -118,8 +118,8 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
svalBuilder.makeZeroVal(T),
getContext().IntTy);
- DefinedOrUnknownSVal *Constraint =
- dyn_cast<DefinedOrUnknownSVal>(&Constraint_untested);
+ llvm::Optional<DefinedOrUnknownSVal> Constraint =
+ Constraint_untested.getAs<DefinedOrUnknownSVal>();
if (!Constraint)
break;
@@ -138,7 +138,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
const MemRegion *R = state->getRegion(SelfD, InitLoc);
SVal V = state->getSVal(loc::MemRegionVal(R));
- if (const Loc *LV = dyn_cast<Loc>(&V)) {
+ if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
// Assume that the pointer value in 'self' is non-null.
state = state->assume(*LV, true);
assert(state && "'self' cannot be null");
@@ -154,7 +154,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) {
if (SFC->getParent() == 0) {
loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
SVal V = state->getSVal(L);
- if (const Loc *LV = dyn_cast<Loc>(&V)) {
+ if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
state = state->assume(*LV, true);
assert(state && "'this' cannot be null");
}
@@ -172,7 +172,7 @@ static ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
const Expr *E) {
SVal V = State->getSVal(E, LC);
- if (isa<NonLoc>(V)) {
+ if (V.getAs<NonLoc>()) {
MemRegionManager &MRMgr = State->getStateManager().getRegionManager();
const MemRegion *R = MRMgr.getCXXTempObjectRegion(E, LC);
State = State->bindLoc(loc::MemRegionVal(R), V);
@@ -472,8 +472,8 @@ void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
- VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
- Dtor.getTriggerStmt(), /*IsBase=*/false, Pred, Dst);
+ VisitCXXDestructor(varType, dest.castAs<loc::MemRegionVal>().getRegion(),
+ Dtor.getTriggerStmt(), /*IsBase=*/ false, Pred, Dst);
}
void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
@@ -490,8 +490,8 @@ void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
QualType BaseTy = D.getBaseSpecifier()->getType();
SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
- VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
- CurDtor->getBody(), /*IsBase=*/true, Pred, Dst);
+ VisitCXXDestructor(BaseTy, BaseVal.castAs<loc::MemRegionVal>().getRegion(),
+ CurDtor->getBody(), /*IsBase=*/ true, Pred, Dst);
}
void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
@@ -503,10 +503,11 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
LCtx->getCurrentStackFrame());
- SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
+ SVal FieldVal =
+ State->getLValue(Member, State->getSVal(ThisVal).castAs<Loc>());
VisitCXXDestructor(Member->getType(),
- cast<loc::MemRegionVal>(FieldVal).getRegion(),
+ FieldVal.castAs<loc::MemRegionVal>().getRegion(),
CurDtor->getBody(), /*IsBase=*/false, Pred, Dst);
}
@@ -1287,7 +1288,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term,
continue;
}
- DefinedSVal V = cast<DefinedSVal>(X);
+ DefinedSVal V = X.castAs<DefinedSVal>();
ProgramStateRef StTrue, StFalse;
tie(StTrue, StFalse) = PrevState->assume(V);
@@ -1327,8 +1328,8 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
typedef IndirectGotoNodeBuilder::iterator iterator;
- if (isa<loc::GotoLabel>(V)) {
- const LabelDecl *L = cast<loc::GotoLabel>(V).getLabel();
+ if (llvm::Optional<loc::GotoLabel> LV = V.getAs<loc::GotoLabel>()) {
+ const LabelDecl *L = LV->getLabel();
for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) {
if (I.getLabel() == L) {
@@ -1340,7 +1341,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) {
llvm_unreachable("No block with label.");
}
- if (isa<loc::ConcreteInt>(V) || isa<UndefinedVal>(V)) {
+ if (V.getAs<loc::ConcreteInt>() || V.getAs<UndefinedVal>()) {
// Dispatch to the first target and mark it as a sink.
//ExplodedNode* N = builder.generateNode(builder.begin(), state, true);
// FIXME: add checker visit.
@@ -1394,7 +1395,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
return;
}
- DefinedOrUnknownSVal CondV = cast<DefinedOrUnknownSVal>(CondV_untested);
+ DefinedOrUnknownSVal CondV = CondV_untested.castAs<DefinedOrUnknownSVal>();
ProgramStateRef DefaultSt = state;
@@ -1435,7 +1436,7 @@ void ExprEngine::processSwitch(SwitchNodeBuilder& builder) {
// If CondV evaluates to a constant, then we know that this
// is the *only* case that we can take, so stop evaluating the
// others.
- if (isa<nonloc::ConcreteInt>(CondV))
+ if (CondV.getAs<nonloc::ConcreteInt>())
return;
}
@@ -1529,7 +1530,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
// results in boolean contexts.
SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
currBldrCtx->blockCount());
- state = state->assume(cast<DefinedOrUnknownSVal>(V), true);
+ state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
ProgramPoint::PostLValueKind);
return;
@@ -1646,7 +1647,8 @@ ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
bool escapes = true;
// TODO: Move to StoreManager.
- if (loc::MemRegionVal *regionLoc = dyn_cast<loc::MemRegionVal>(&Loc)) {
+ if (llvm::Optional<loc::MemRegionVal> regionLoc =
+ Loc.getAs<loc::MemRegionVal>()) {
escapes = !regionLoc->getRegion()->hasStackStorage();
if (!escapes) {
@@ -1754,7 +1756,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
// If the location is not a 'Loc', it will already be handled by
// the checkers. There is nothing left to do.
- if (!isa<Loc>(location)) {
+ if (!location.getAs<Loc>()) {
const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/0, /*tag*/0);
ProgramStateRef state = Pred->getState();
state = processPointerEscapedOnBind(state, location, Val);
@@ -1773,11 +1775,12 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE,
// When binding the value, pass on the hint that this is a initialization.
// For initializations, we do not need to inform clients of region
// changes.
- state = state->bindLoc(cast<Loc>(location),
+ state = state->bindLoc(location.castAs<Loc>(),
Val, /* notifyChanges = */ !atDeclInit);
const MemRegion *LocReg = 0;
- if (loc::MemRegionVal *LocRegVal = dyn_cast<loc::MemRegionVal>(&location)) {
+ if (llvm::Optional<loc::MemRegionVal> LocRegVal =
+ location.getAs<loc::MemRegionVal>()) {
LocReg = LocRegVal->getRegion();
}
@@ -1826,7 +1829,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst,
const ProgramPointTag *tag,
QualType LoadTy)
{
- assert(!isa<NonLoc>(location) && "location cannot be a NonLoc.");
+ assert(!location.getAs<NonLoc>() && "location cannot be a NonLoc.");
// Are we loading from a region? This actually results in two loads; one
// to fetch the address of the referenced value and one to fetch the
@@ -1885,7 +1888,7 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst,
if (location.isValid()) {
if (LoadTy.isNull())
LoadTy = BoundEx->getType();
- V = state->getSVal(cast<Loc>(location), LoadTy);
+ V = state->getSVal(location.castAs<Loc>(), LoadTy);
}
Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag,
@@ -1955,7 +1958,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst,
ProgramStateRef state = Pred->getState();
SVal V = state->getSVal(Ex, Pred->getLocationContext());
- nonloc::SymbolVal *SEV = dyn_cast<nonloc::SymbolVal>(&V);
+ llvm::Optional<nonloc::SymbolVal> SEV = V.getAs<nonloc::SymbolVal>();
if (SEV && SEV->isExpression()) {
const std::pair<const ProgramPointTag *, const ProgramPointTag*> &tags =
geteagerlyAssumeBinOpBifurcationTags();
@@ -1995,10 +1998,10 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
OE = A->end_outputs(); OI != OE; ++OI) {
SVal X = state->getSVal(*OI, Pred->getLocationContext());
- assert (!isa<NonLoc>(X)); // Should be an Lval, or unknown, undef.
+ assert (!X.getAs<NonLoc>()); // Should be an Lval, or unknown, undef.
- if (isa<Loc>(X))
- state = state->bindLoc(cast<Loc>(X), UnknownVal());
+ if (llvm::Optional<Loc> LV = X.getAs<Loc>())
+ state = state->bindLoc(*LV, UnknownVal());
}
Bldr.generateNode(A, Pred, state);
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index f33f56176d..fe132df4b5 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -67,12 +67,12 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B,
// TODO: This can be removed after we enable history tracking with
// SymSymExpr.
unsigned Count = currBldrCtx->blockCount();
- if (isa<Loc>(LeftV) &&
+ if (LeftV.getAs<Loc>() &&
RHS->getType()->isIntegerType() && RightV.isUnknown()) {
RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(),
Count);
}
- if (isa<Loc>(RightV) &&
+ if (RightV.getAs<Loc>() &&
LHS->getType()->isIntegerType() && LeftV.isUnknown()) {
LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(),
Count);
@@ -480,10 +480,13 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
} else {
// We bound the temp obj region to the CXXConstructExpr. Now recover
// the lazy compound value when the variable is not a reference.
- if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
- !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
- InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
- assert(isa<nonloc::LazyCompoundVal>(InitVal));
+ if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() &&
+ !VD->getType()->isReferenceType()) {
+ if (llvm::Optional<loc::MemRegionVal> M =
+ InitVal.getAs<loc::MemRegionVal>()) {
+ InitVal = state->getSVal(M->getRegion());
+ assert(InitVal.getAs<nonloc::LazyCompoundVal>());
+ }
}
// Recover some path-sensitivity if a scalar value evaluated to
@@ -558,7 +561,7 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
if (RHSVal.isUndef()) {
X = RHSVal;
} else {
- DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
+ DefinedOrUnknownSVal DefinedRHS = RHSVal.castAs<DefinedOrUnknownSVal>();
ProgramStateRef StTrue, StFalse;
llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
if (StTrue) {
@@ -810,11 +813,11 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
llvm_unreachable("Invalid Opcode.");
case UO_Not:
// FIXME: Do we need to handle promotions?
- state = state->BindExpr(U, LCtx, evalComplement(cast<NonLoc>(V)));
+ state = state->BindExpr(U, LCtx, evalComplement(V.castAs<NonLoc>()));
break;
case UO_Minus:
// FIXME: Do we need to handle promotions?
- state = state->BindExpr(U, LCtx, evalMinus(cast<NonLoc>(V)));
+ state = state->BindExpr(U, LCtx, evalMinus(V.castAs<NonLoc>()));
break;
case UO_LNot:
// C99 6.5.3.3: "The expression !E is equivalent to (0==E)."
@@ -822,17 +825,16 @@ void ExprEngine::VisitUnaryOperator(const UnaryOperator* U,
// Note: technically we do "E == 0", but this is the same in the
// transfer functions as "0 == E".
SVal Result;
- if (isa<Loc>(V)) {
+ if (llvm::Optional<Loc> LV = V.getAs<Loc>()) {
Loc X = svalBuilder.makeNull();
- Result = evalBinOp(state, BO_EQ, cast<Loc>(V), X,
- U->getType());
+ Result = evalBinOp(state, BO_EQ, *LV, X, U->getType());
}
else if (Ex->getType()->isFloatingType()) {
// FIXME: handle floating point types.
Result = UnknownVal();
} else {
nonloc::ConcreteInt X(getBasicVals().getValue(0, Ex->getType()));
- Result = evalBinOp(state, BO_EQ, cast<NonLoc>(V), X,
+ Result = evalBinOp(state, BO_EQ, V.castAs<NonLoc>(), X,
U->getType());
}
@@ -874,7 +876,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U,
Bldr.generateNode(U, *I, state->BindExpr(U, LCtx, V2_untested));
continue;
}
- DefinedSVal V2 = cast<DefinedSVal>(V2_untested);
+ DefinedSVal V2 = V2_untested.castAs<DefinedSVal>();
// Handle all other values.
BinaryOperator::Opcode Op = U->isIncrementOp() ? BO_Add : BO_Sub;
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index fdd50a6b54..7e86a56759 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -64,7 +64,7 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
SVal V = Call.getArgSVal(0);
// Make sure the value being copied is not unknown.
- if (const Loc *L = dyn_cast<Loc>(&V))
+ if (llvm::Optional<Loc> L = V.getAs<Loc>())
V = Pred->getState()->getSVal(*L);
evalBind(Dst, CtorExpr, Pred, ThisVal, V, true);
@@ -287,7 +287,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
if (CNE->isArray()) {
// FIXME: allocating an array requires simulating the constructors.
// For now, just return a symbolicated region.
- const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion();
+ const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
const ElementRegion *EleReg =
getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
@@ -319,8 +319,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
(void)ObjTy;
assert(!ObjTy->isRecordType());
SVal Location = State->getSVal(CNE, LCtx);
- if (isa<Loc>(Location))
- State = State->bindLoc(cast<Loc>(Location), State->getSVal(Init, LCtx));
+ if (llvm::Optional<Loc> LV = Location.getAs<Loc>())
+ State = State->bindLoc(*LV, State->getSVal(Init, LCtx));
}
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 1d006b09cc..0d4673cdbf 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -121,7 +121,7 @@ static std::pair<const Stmt*,
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
StoreManager &StoreMgr) {
// For now, the only adjustments we handle apply only to locations.
- if (!isa<Loc>(V))
+ if (!V.getAs<Loc>())
return V;
// If the types already match, don't do any unnecessary work.
@@ -266,7 +266,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
// If the constructed object is a temporary prvalue, get its bindings.
if (isTemporaryPRValue(CCE, ThisV))
- ThisV = state->getSVal(cast<Loc>(ThisV));
+ ThisV = state->getSVal(ThisV.castAs<Loc>());
state = state->BindExpr(CCE, callerCtx, ThisV);
}
@@ -709,7 +709,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
// If the constructed object is a temporary prvalue, get its bindings.
if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
- ThisV = State->getSVal(cast<Loc>(ThisV));
+ ThisV = State->getSVal(ThisV.castAs<Loc>());
return State->BindExpr(E, LCtx, ThisV);
}
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index de73dd7c3e..69a5052e90 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -103,8 +103,9 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S,
// Handle the case where the container has no elements.
SVal FalseV = svalBuilder.makeTruthVal(0);
ProgramStateRef noElems = state->BindExpr(S, LCtx, FalseV);
-
- if (loc::MemRegionVal *MV = dyn_cast<loc::MemRegionVal>(&elementV))
+
+ if (llvm::Optional<loc::MemRegionVal> MV =
+ elementV.getAs<loc::MemRegionVal>())
if (const TypedValueRegion *R =
dyn_cast<TypedValueRegion>(MV->getRegion())) {
// FIXME: The proper thing to do is to really iterate over the
@@ -161,8 +162,9 @@ void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
SVal recVal = UpdatedMsg->getReceiverSVal();
if (!recVal.isUndef()) {
// Bifurcate the state into nil and non-nil ones.
- DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
-
+ DefinedOrUnknownSVal receiverVal =
+ recVal.castAs<DefinedOrUnknownSVal>();
+
ProgramStateRef notNilState, nilState;
llvm::tie(notNilState, nilState) = State->assume(receiverVal);
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index a0abe42253..c48343a824 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1044,7 +1044,8 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const {
// FIXME: generalize to symbolic offsets.
SVal index = ER->getIndex();
- if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
+ if (llvm::Optional<nonloc::ConcreteInt> CI =
+ index.getAs<nonloc::ConcreteInt>()) {
// Update the offset.
int64_t i = CI->getValue().getSExtValue();
@@ -1171,7 +1172,8 @@ RegionOffset MemRegion::getAsOffset() const {
}
SVal Index = ER->getIndex();
- if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
+ if (llvm::Optional<nonloc::ConcreteInt> CI =
+ Index.getAs<nonloc::ConcreteInt>()) {
// Don't bother calculating precise offsets if we already have a
// symbolic offset somewhere in the chain.
if (SymbolicOffsetBase)
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index 3c6ff6cac6..c723bc8844 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -1029,7 +1029,7 @@ std::string StackHintGeneratorForSymbol::getMessage(const ExplodedNode *N){
}
// Check if the parameter is a pointer to the symbol.
- if (const loc::MemRegionVal *Reg = dyn_cast<loc::MemRegionVal>(&SV)) {
+ if (llvm::Optional<loc::MemRegionVal> Reg = SV.getAs<loc::MemRegionVal>()) {
SVal PSV = State->getSVal(Reg->getRegion());
SymbolRef AS = PSV.getAsLocSymbol();
if (AS == Sym) {
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index a3db3764fb..6c76ebfbe5 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -132,7 +132,7 @@ ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const
ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
ProgramStateManager &Mgr = getStateManager();
- const MemRegion *R = cast<loc::MemRegionVal>(loc).getRegion();
+ const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
ProgramStateRef new_state = makeWithStore(newStore);
return Mgr.getOwningEngine() ?
@@ -189,7 +189,7 @@ ProgramState::invalidateRegionsImpl(ArrayRef<const MemRegion *> Regions,
}
ProgramStateRef ProgramState::killBinding(Loc LV) const {
- assert(!isa<loc::MemRegionVal>(LV) && "Use invalidateRegion instead.");
+ assert(!LV.getAs<loc::MemRegionVal>() && "Use invalidateRegion instead.");
Store OldStore = getStore();
const StoreRef &newStore =
@@ -253,7 +253,7 @@ SVal ProgramState::getSVal(Loc location, QualType T) const {
// not unsigned.
const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
- if (isa<Loc>(V))
+ if (V.getAs<Loc>())
return loc::ConcreteInt(NewV);
else
return nonloc::ConcreteInt(NewV);
@@ -301,28 +301,27 @@ ProgramStateRef ProgramState::assumeInBound(DefinedOrUnknownSVal Idx,
// Adjust the index.
SVal newIdx = svalBuilder.evalBinOpNN(this, BO_Add,
- cast<NonLoc>(Idx), Min, indexTy);
+ Idx.castAs<NonLoc>(), Min, indexTy);
if (newIdx.isUnknownOrUndef())
return this;
// Adjust the upper bound.
SVal newBound =
- svalBuilder.evalBinOpNN(this, BO_Add, cast<NonLoc>(UpperBound),
+ svalBuilder.evalBinOpNN(this, BO_Add, UpperBound.castAs<NonLoc>(),
Min, indexTy);
if (newBound.isUnknownOrUndef())
return this;
// Build the actual comparison.
- SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT,
- cast<NonLoc>(newIdx), cast<NonLoc>(newBound),
- Ctx.IntTy);
+ SVal inBound = svalBuilder.evalBinOpNN(this, BO_LT, newIdx.castAs<NonLoc>(),
+ newBound.castAs<NonLoc>(), Ctx.IntTy);
if (inBound.isUnknownOrUndef())
return this;
// Finally, let the constraint manager take care of it.
ConstraintManager &CM = SM.getConstraintManager();
- return CM.assume(this, cast<DefinedSVal>(inBound), Assumption);
+ return CM.assume(this, inBound.castAs<DefinedSVal>(), Assumption);
}
ProgramStateRef ProgramStateManager::getInitialState(const LocationContext *InitLoc) {
@@ -509,10 +508,11 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) {
}