diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 46 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/CallEvent.cpp | 7 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/Environment.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngine.cpp | 59 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 30 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 8 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineObjC.cpp | 10 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 2 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 27 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 76 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 39 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SVals.cpp | 54 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp | 19 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 72 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/Store.cpp | 25 |
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) { } |