diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index f939416cd819..e7f79ac88933 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -1,4 +1,4 @@ -//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=// +//===- ExprEngine.h - Path-Sensitive Expression-Level Dataflow --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,36 +18,68 @@ #include "clang/AST/Expr.h" #include "clang/AST/Type.h" +#include "clang/Analysis/CFG.h" #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" +#include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" +#include "llvm/ADT/ArrayRef.h" +#include +#include namespace clang { class AnalysisDeclContextManager; +class AnalyzerOptions; +class ASTContext; +class ConstructionContext; +class CXXBindTemporaryExpr; class CXXCatchStmt; class CXXConstructExpr; class CXXDeleteExpr; class CXXNewExpr; -class CXXTemporaryObjectExpr; class CXXThisExpr; +class Decl; +class DeclStmt; +class GCCAsmStmt; +class LambdaExpr; +class LocationContext; class MaterializeTemporaryExpr; +class MSAsmStmt; +class NamedDecl; class ObjCAtSynchronizedStmt; class ObjCForCollectionStmt; +class ObjCIvarRefExpr; +class ObjCMessageExpr; +class ReturnStmt; +class Stmt; namespace cross_tu { + class CrossTranslationUnitContext; -} + +} // namespace cross_tu namespace ento { -class AnalysisManager; +class BasicValueFactory; class CallEvent; -class CXXConstructorCall; +class CheckerManager; +class ConstraintManager; +class CXXTempObjectRegion; +class MemRegion; +class RegionAndSymbolInvalidationTraits; +class SymbolManager; class ExprEngine : public SubEngine { public: @@ -55,6 +87,7 @@ public: enum InliningModes { /// Follow the default settings for inlining callees. Inline_Regular = 0, + /// Do minimal inlining of callees. Inline_Minimal = 0x1 }; @@ -64,11 +97,14 @@ public: /// This call is a constructor or a destructor for which we do not currently /// compute the this-region correctly. bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false; + /// This call is a constructor or a destructor for a single element within /// an array, a part of array construction or destruction. bool IsArrayCtorOrDtor = false; + /// This call is a constructor or a destructor of a temporary value. bool IsTemporaryCtorOrDtor = false; + /// This call is a constructor for a temporary that is lifetime-extended /// by binding a smaller object within it to a reference, for example /// 'const int &x = C().x;'. @@ -87,19 +123,19 @@ private: CoreEngine Engine; /// G - the simulation graph. - ExplodedGraph& G; + ExplodedGraph &G; /// StateMgr - Object that manages the data for all created states. ProgramStateManager StateMgr; /// SymMgr - Object that manages the symbol information. - SymbolManager& SymMgr; + SymbolManager &SymMgr; /// svalBuilder - SValBuilder object that creates SVals from expressions. SValBuilder &svalBuilder; - unsigned int currStmtIdx; - const NodeBuilderContext *currBldrCtx; + unsigned int currStmtIdx = 0; + const NodeBuilderContext *currBldrCtx = nullptr; /// Helper object to determine if an Objective-C message expression /// implicitly never returns. @@ -153,7 +189,7 @@ public: SValBuilder &getSValBuilder() { return svalBuilder; } - BugReporter& getBugReporter() { return BR; } + BugReporter &getBugReporter() { return BR; } cross_tu::CrossTranslationUnitContext * getCrossTranslationUnitContext() override { @@ -178,14 +214,14 @@ public: /// Visualize a trimmed ExplodedGraph that only contains paths to the given /// nodes. - void ViewGraph(ArrayRef Nodes); + void ViewGraph(ArrayRef Nodes); /// getInitialState - Return the initial state used for the root vertex /// in the ExplodedGraph. ProgramStateRef getInitialState(const LocationContext *InitLoc) override; - ExplodedGraph& getGraph() { return G; } - const ExplodedGraph& getGraph() const { return G; } + ExplodedGraph &getGraph() { return G; } + const ExplodedGraph &getGraph() const { return G; } /// \brief Run the analyzer's garbage collection - remove dead symbols and /// bindings from the state. @@ -331,22 +367,22 @@ public: const char *Sep, const LocationContext *LCtx = nullptr) override; - ProgramStateManager& getStateManager() override { return StateMgr; } + ProgramStateManager &getStateManager() override { return StateMgr; } - StoreManager& getStoreManager() { return StateMgr.getStoreManager(); } + StoreManager &getStoreManager() { return StateMgr.getStoreManager(); } - ConstraintManager& getConstraintManager() { + ConstraintManager &getConstraintManager() { return StateMgr.getConstraintManager(); } // FIXME: Remove when we migrate over to just using SValBuilder. - BasicValueFactory& getBasicVals() { + BasicValueFactory &getBasicVals() { return StateMgr.getBasicVals(); } // FIXME: Remove when we migrate over to just using ValueManager. - SymbolManager& getSymbolManager() { return SymMgr; } - const SymbolManager& getSymbolManager() const { return SymMgr; } + SymbolManager &getSymbolManager() { return SymMgr; } + const SymbolManager &getSymbolManager() const { return SymMgr; } // Functions for external checking of whether we have unfinished work bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); } @@ -392,7 +428,7 @@ public: /// VisitCast - Transfer function logic for all casts (implicit and explicit). void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred, - ExplodedNodeSet &Dst); + ExplodedNodeSet &Dst); /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, @@ -419,7 +455,7 @@ public: /// VisitMemberExpr - Transfer function for member expressions. void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, - ExplodedNodeSet &Dst); + ExplodedNodeSet &Dst); /// VisitAtomicExpr - Transfer function for builtin atomic expressions void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, @@ -451,7 +487,7 @@ public: /// VisitUnaryExprOrTypeTraitExpr - Transfer function for sizeof. void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex, - ExplodedNode *Pred, ExplodedNodeSet &Dst); + ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitUnaryOperator - Transfer function logic for unary operators. void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, @@ -501,7 +537,7 @@ public: void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex); - std::pair + std::pair geteagerlyAssumeBinOpBifurcationTags(); SVal evalMinus(SVal X) { @@ -529,7 +565,6 @@ public: StmtNodeBuilder &Bldr); public: - SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc L, NonLoc R, QualType T) { return svalBuilder.evalBinOpNN(state, op, L, R, T); @@ -775,8 +810,8 @@ struct ProgramStateTrait : static void *GDMIndex() { static int index = 0; return &index; } }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang -#endif +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPRENGINE_H diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index e6f8b8f3920a..1569e86b57c5 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1,4 +1,4 @@ -//=-- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-= +//===- ExprEngine.cpp - Path-Sensitive Expression-Level Dataflow ----------===// // // The LLVM Compiler Infrastructure // @@ -15,32 +15,74 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "PrettyStackTraceLocationContext.h" -#include "clang/AST/CharUnits.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/ParentMap.h" -#include "clang/Analysis/CFGStmtMap.h" +#include "clang/AST/PrettyPrinter.h" +#include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" -#include "clang/Basic/Builtins.h" +#include "clang/AST/Type.h" +#include "clang/Analysis/AnalysisDeclContext.h" +#include "clang/Analysis/CFG.h" +#include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/PrettyStackTrace.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" -#include "clang/CrossTU/CrossTranslationUnit.h" +#include "clang/Basic/Specifiers.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/ImmutableMap.h" +#include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/DOTGraphTraits.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/GraphWriter.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" - -#ifndef NDEBUG -#include "llvm/Support/GraphWriter.h" -#endif +#include +#include +#include +#include +#include +#include +#include using namespace clang; using namespace ento; -using llvm::APSInt; #define DEBUG_TYPE "ExprEngine" @@ -55,10 +97,10 @@ STATISTIC(NumMaxBlockCountReachedInInlined, STATISTIC(NumTimesRetriedWithoutInlining, "The # of times we re-evaluated a call without inlining"); -typedef llvm::ImmutableMap, - const CXXTempObjectRegion *> - InitializedTemporariesMap; +using InitializedTemporariesMap = + llvm::ImmutableMap, + const CXXTempObjectRegion *>; // Keeps track of whether CXXBindTemporaryExpr nodes have been evaluated. // The StackFrameContext assures that nested calls due to inlined recursive @@ -66,10 +108,10 @@ typedef llvm::ImmutableMap, - const CXXTempObjectRegion *> - TemporaryMaterializationMap; +using TemporaryMaterializationMap = + llvm::ImmutableMap, + const CXXTempObjectRegion *>; // Keeps track of temporaries that will need to be materialized later. // The StackFrameContext assures that nested calls due to inlined recursive @@ -77,10 +119,9 @@ typedef llvm::ImmutableMap, - SVal> - CXXNewAllocatorValuesMap; +using CXXNewAllocatorValuesMap = + llvm::ImmutableMap, + SVal>; // Keeps track of return values of various operator new() calls between // evaluation of the inlined operator new(), through the constructor call, @@ -99,25 +140,21 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(CXXNewAllocatorValues, static const char* TagProviderName = "ExprEngine"; -ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, AnalysisManager &mgr, - bool gcEnabled, SetOfConstDecls *VisitedCalleesIn, +ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, + AnalysisManager &mgr, bool gcEnabled, + SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn) - : CTU(CTU), AMgr(mgr), - AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), - Engine(*this, FS, mgr.getAnalyzerOptions()), - G(Engine.getGraph()), - StateMgr(getContext(), mgr.getStoreManagerCreator(), - mgr.getConstraintManagerCreator(), G.getAllocator(), - this), - SymMgr(StateMgr.getSymbolManager()), - svalBuilder(StateMgr.getSValBuilder()), - currStmtIdx(0), currBldrCtx(nullptr), - ObjCNoRet(mgr.getASTContext()), - ObjCGCEnabled(gcEnabled), BR(mgr, *this), - VisitedCallees(VisitedCalleesIn), - HowToInline(HowToInlineIn) -{ + : CTU(CTU), AMgr(mgr), + AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()), + Engine(*this, FS, mgr.getAnalyzerOptions()), G(Engine.getGraph()), + StateMgr(getContext(), mgr.getStoreManagerCreator(), + mgr.getConstraintManagerCreator(), G.getAllocator(), + this), + SymMgr(StateMgr.getSymbolManager()), + svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()), + ObjCGCEnabled(gcEnabled), BR(mgr, *this), + VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) { unsigned TrimInterval = mgr.options.getGraphTrimInterval(); if (TrimInterval != 0) { // Enable eager node reclaimation when constructing the ExplodedGraph. @@ -141,8 +178,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { // FIXME: It would be nice if we had a more general mechanism to add // such preconditions. Some day. do { - - if (const FunctionDecl *FD = dyn_cast(D)) { + if (const auto *FD = dyn_cast(D)) { // Precondition: the first argument of 'main' is an integer guaranteed // to be > 0. const IdentifierInfo *II = FD->getIdentifier(); @@ -151,7 +187,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { const ParmVarDecl *PD = FD->getParamDecl(0); QualType T = PD->getType(); - const BuiltinType *BT = dyn_cast(T); + const auto *BT = dyn_cast(T); if (!BT || !BT->isInteger()) break; @@ -175,9 +211,9 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { } break; } - while (0); + while (false); - if (const ObjCMethodDecl *MD = dyn_cast(D)) { + if (const auto *MD = dyn_cast(D)) { // Precondition: 'self' is always non-null upon entry to an Objective-C // method. const ImplicitParamDecl *SelfD = MD->getSelfDecl(); @@ -191,7 +227,7 @@ ProgramStateRef ExprEngine::getInitialState(const LocationContext *InitLoc) { } } - if (const CXXMethodDecl *MD = dyn_cast(D)) { + if (const auto *MD = dyn_cast(D)) { if (!MD->isStatic()) { // Precondition: 'this' is always non-null upon entry to the // top-level function. This is our starting assumption for @@ -274,8 +310,7 @@ ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State, // into that region. This is not correct, but it is better than nothing. bool FoundOriginalMaterializationRegion = false; const TypedValueRegion *TR = nullptr; - if (const MaterializeTemporaryExpr *MT = - dyn_cast(Result)) { + if (const auto *MT = dyn_cast(Result)) { auto Key = std::make_pair(MT, LC->getCurrentStackFrame()); if (const CXXTempObjectRegion *const *TRPtr = State->get(Key)) { @@ -605,7 +640,6 @@ static bool shouldRemoveDeadBindings(AnalysisManager &AMgr, const Stmt *S, const ExplodedNode *Pred, const LocationContext *LC) { - // Are we never purging state values? if (AMgr.options.AnalysisPurgeOpt == PurgeNone) return false; @@ -701,9 +735,8 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, // environment, the store, and the constraints cleaned up but have the // user-supplied states as the predecessors. StmtNodeBuilder Bldr(CheckedSet, Out, *currBldrCtx); - for (ExplodedNodeSet::const_iterator - I = CheckedSet.begin(), E = CheckedSet.end(); I != E; ++I) { - ProgramStateRef CheckerState = (*I)->getState(); + for (const auto I : CheckedSet) { + ProgramStateRef CheckerState = I->getState(); // The constraint manager has not been cleaned up yet, so clean up now. CheckerState = getConstraintManager().removeDeadBindings(CheckerState, @@ -720,7 +753,7 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, // generate a transition to that state. ProgramStateRef CleanedCheckerSt = StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState); - Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K); + Bldr.generateNode(DiagnosticStmt, I, CleanedCheckerSt, &cleanupTag, K); } } } @@ -744,11 +777,10 @@ void ExprEngine::ProcessStmt(const Stmt *currStmt, ExplodedNode *Pred) { // Visit the statement. ExplodedNodeSet Dst; - for (ExplodedNodeSet::iterator I = CleanedStates.begin(), - E = CleanedStates.end(); I != E; ++I) { + for (const auto I : CleanedStates) { ExplodedNodeSet DstI; // Visit the statement. - Visit(currStmt, *I, DstI); + Visit(currStmt, I, DstI); Dst.insert(DstI); } @@ -783,10 +815,8 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init, "Error evaluating initializer"); // We don't clean up dead bindings here. - const StackFrameContext *stackFrame = - cast(Pred->getLocationContext()); - const CXXConstructorDecl *decl = - cast(stackFrame->getDecl()); + const auto *stackFrame = cast(Pred->getLocationContext()); + const auto *decl = cast(stackFrame->getDecl()); ProgramStateRef State = Pred->getState(); SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame)); @@ -798,7 +828,7 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init, if (BMI->isAnyMemberInitializer()) { // Constructors build the object directly in the field, // but non-objects must be copied in from the initializer. - if (auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) { + if (const auto *CtorExpr = findDirectConstructorForCurrentCFGElement()) { assert(BMI->getInit()->IgnoreImplicit() == CtorExpr); (void)CtorExpr; // The field was directly constructed, so there is no need to bind. @@ -854,10 +884,8 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init, PostInitializer PP(BMI, FieldLoc.getAsRegion(), stackFrame); ExplodedNodeSet Dst; NodeBuilder Bldr(Tmp, Dst, *currBldrCtx); - for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { - ExplodedNode *N = *I; - Bldr.generateNode(PP, N->getState(), N); - } + for (const auto I : Tmp) + Bldr.generateNode(PP, I->getState(), I); // Enqueue the new nodes onto the work list. Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx); @@ -985,7 +1013,7 @@ void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst) { const LocationContext *LCtx = Pred->getLocationContext(); - const CXXDestructorDecl *CurDtor = cast(LCtx->getDecl()); + const auto *CurDtor = cast(LCtx->getDecl()); Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor, LCtx->getCurrentStackFrame()); SVal ThisVal = Pred->getState()->getSVal(ThisPtr); @@ -1007,7 +1035,7 @@ void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D, ProgramStateRef State = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); - const CXXDestructorDecl *CurDtor = cast(LCtx->getDecl()); + const auto *CurDtor = cast(LCtx->getDecl()); Loc ThisVal = getSValBuilder().getCXXThis(CurDtor, LCtx->getCurrentStackFrame()); SVal FieldVal = @@ -1119,11 +1147,13 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, } namespace { + class CollectReachableSymbolsCallback final : public SymbolVisitor { InvalidatedSymbols Symbols; public: explicit CollectReachableSymbolsCallback(ProgramStateRef State) {} + const InvalidatedSymbols &getSymbols() const { return Symbols; } bool VisitSymbol(SymbolRef Sym) override { @@ -1131,7 +1161,8 @@ public: return true; } }; -} // end anonymous namespace + +} // namespace void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &DstTop) { @@ -1221,8 +1252,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: - case Stmt::CapturedStmtClass: - { + case Stmt::CapturedStmtClass: { const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); Engine.addAbortedBlock(node, currBldrCtx->getBlock()); break; @@ -1351,16 +1381,15 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, StmtNodeBuilder Bldr2(PreVisit, Tmp, *currBldrCtx); const Expr *ArgE; - if (const CXXDefaultArgExpr *DefE = dyn_cast(S)) + if (const auto *DefE = dyn_cast(S)) ArgE = DefE->getExpr(); - else if (const CXXDefaultInitExpr *DefE = dyn_cast(S)) + else if (const auto *DefE = dyn_cast(S)) ArgE = DefE->getExpr(); else llvm_unreachable("unknown constant wrapper kind"); bool IsTemporary = false; - if (const MaterializeTemporaryExpr *MTE = - dyn_cast(ArgE)) { + if (const auto *MTE = dyn_cast(ArgE)) { ArgE = MTE->GetTemporaryExpr(); IsTemporary = true; } @@ -1370,15 +1399,14 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ConstantVal = UnknownVal(); const LocationContext *LCtx = Pred->getLocationContext(); - for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end(); - I != E; ++I) { - ProgramStateRef State = (*I)->getState(); + for (const auto I : PreVisit) { + ProgramStateRef State = I->getState(); State = State->BindExpr(S, LCtx, *ConstantVal); if (IsTemporary) State = createTemporaryRegionIfNeeded(State, LCtx, cast(S), cast(S)); - Bldr2.generateNode(S, *I, State); + Bldr2.generateNode(S, I, State); } getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); @@ -1399,12 +1427,10 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet Tmp; StmtNodeBuilder Bldr2(preVisit, Tmp, *currBldrCtx); - const Expr *Ex = cast(S); + const auto *Ex = cast(S); QualType resultType = Ex->getType(); - for (ExplodedNodeSet::iterator it = preVisit.begin(), et = preVisit.end(); - it != et; ++it) { - ExplodedNode *N = *it; + for (const auto N : preVisit) { const LocationContext *LCtx = N->getLocationContext(); SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx, resultType, @@ -1475,7 +1501,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; case Stmt::BinaryOperatorClass: { - const BinaryOperator* B = cast(S); + const auto *B = cast(S); if (B->isLogicalOp()) { Bldr.takeNodes(Pred); VisitLogicalExpr(B, Pred, Dst); @@ -1507,12 +1533,12 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, } case Stmt::CXXOperatorCallExprClass: { - const CXXOperatorCallExpr *OCE = cast(S); + const auto *OCE = cast(S); // For instance method operators, make sure the 'this' argument has a // valid region. const Decl *Callee = OCE->getCalleeDecl(); - if (const CXXMethodDecl *MD = dyn_cast_or_null(Callee)) { + if (const auto *MD = dyn_cast_or_null(Callee)) { if (MD->isInstance()) { ProgramStateRef State = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); @@ -1530,29 +1556,27 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, // FALLTHROUGH LLVM_FALLTHROUGH; } + case Stmt::CallExprClass: case Stmt::CXXMemberCallExprClass: - case Stmt::UserDefinedLiteralClass: { + case Stmt::UserDefinedLiteralClass: Bldr.takeNodes(Pred); VisitCallExpr(cast(S), Pred, Dst); Bldr.addNodes(Dst); break; - } - case Stmt::CXXCatchStmtClass: { + case Stmt::CXXCatchStmtClass: Bldr.takeNodes(Pred); VisitCXXCatchStmt(cast(S), Pred, Dst); Bldr.addNodes(Dst); break; - } case Stmt::CXXTemporaryObjectExprClass: - case Stmt::CXXConstructExprClass: { + case Stmt::CXXConstructExprClass: Bldr.takeNodes(Pred); VisitCXXConstructExpr(cast(S), Pred, Dst); Bldr.addNodes(Dst); break; - } case Stmt::CXXNewExprClass: { Bldr.takeNodes(Pred); @@ -1561,10 +1585,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); ExplodedNodeSet PostVisit; - for (ExplodedNodeSet::iterator i = PreVisit.begin(), - e = PreVisit.end(); i != e ; ++i) { - VisitCXXNewExpr(cast(S), *i, PostVisit); - } + for (const auto i : PreVisit) + VisitCXXNewExpr(cast(S), i, PostVisit); getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); Bldr.addNodes(Dst); @@ -1574,12 +1596,11 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXDeleteExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet PreVisit; - const CXXDeleteExpr *CDE = cast(S); + const auto *CDE = cast(S); getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); - for (ExplodedNodeSet::iterator i = PreVisit.begin(), - e = PreVisit.end(); i != e ; ++i) - VisitCXXDeleteExpr(CDE, *i, Dst); + for (const auto i : PreVisit) + VisitCXXDeleteExpr(CDE, i, Dst); Bldr.addNodes(Dst); break; @@ -1589,7 +1610,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::ChooseExprClass: { // __builtin_choose_expr Bldr.takeNodes(Pred); - const ChooseExpr *C = cast(S); + const auto *C = cast(S); VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); Bldr.addNodes(Dst); break; @@ -1610,8 +1631,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::BinaryConditionalOperatorClass: case Stmt::ConditionalOperatorClass: { // '?' operator Bldr.takeNodes(Pred); - const AbstractConditionalOperator *C - = cast(S); + const auto *C = cast(S); VisitGuardedExpr(C, C->getTrueExpr(), C->getFalseExpr(), Pred, Dst); Bldr.addNodes(Dst); break; @@ -1625,7 +1645,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::DeclRefExprClass: { Bldr.takeNodes(Pred); - const DeclRefExpr *DE = cast(S); + const auto *DE = cast(S); VisitCommonDeclRefExpr(DE, DE->getDecl(), Pred, Dst); Bldr.addNodes(Dst); break; @@ -1646,7 +1666,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXFunctionalCastExprClass: case Stmt::ObjCBridgedCastExprClass: { Bldr.takeNodes(Pred); - const CastExpr *C = cast(S); + const auto *C = cast(S); ExplodedNodeSet dstExpr; VisitCast(C, C->getSubExpr(), Pred, dstExpr); @@ -1658,14 +1678,12 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Expr::MaterializeTemporaryExprClass: { Bldr.takeNodes(Pred); - const MaterializeTemporaryExpr *MTE = cast(S); + const auto *MTE = cast(S); ExplodedNodeSet dstPrevisit; getCheckerManager().runCheckersForPreStmt(dstPrevisit, Pred, MTE, *this); ExplodedNodeSet dstExpr; - for (ExplodedNodeSet::iterator i = dstPrevisit.begin(), - e = dstPrevisit.end(); i != e ; ++i) { - CreateCXXTemporaryObject(MTE, *i, dstExpr); - } + for (const auto i : dstPrevisit) + CreateCXXTemporaryObject(MTE, i, dstExpr); getCheckerManager().runCheckersForPostStmt(Dst, dstExpr, MTE, *this); Bldr.addNodes(Dst); break; @@ -1726,13 +1744,14 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); ExplodedNodeSet PostVisit; - for (ExplodedNode *Node : PreVisit) + for (const auto Node : PreVisit) VisitOffsetOfExpr(cast(S), Node, PostVisit); getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); Bldr.addNodes(Dst); break; } + case Stmt::UnaryExprOrTypeTraitExprClass: Bldr.takeNodes(Pred); VisitUnaryExprOrTypeTraitExpr(cast(S), @@ -1741,7 +1760,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; case Stmt::StmtExprClass: { - const StmtExpr *SE = cast(S); + const auto *SE = cast(S); if (SE->getSubStmt()->body_empty()) { // Empty statement expression. @@ -1750,7 +1769,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; } - if (Expr *LastExpr = dyn_cast(*SE->getSubStmt()->body_rbegin())) { + if (const auto *LastExpr = + dyn_cast(*SE->getSubStmt()->body_rbegin())) { ProgramStateRef state = Pred->getState(); Bldr.generateNode(SE, Pred, state->BindExpr(SE, Pred->getLocationContext(), @@ -1762,7 +1782,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::UnaryOperatorClass: { Bldr.takeNodes(Pred); - const UnaryOperator *U = cast(S); + const auto *U = cast(S); if (AMgr.options.eagerlyAssumeBinOpBifurcation && (U->getOpcode() == UO_LNot)) { ExplodedNodeSet Tmp; VisitUnaryOperator(U, Pred, Tmp); @@ -1777,7 +1797,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::PseudoObjectExprClass: { Bldr.takeNodes(Pred); ProgramStateRef state = Pred->getState(); - const PseudoObjectExpr *PE = cast(S); + const auto *PE = cast(S); if (const Expr *Result = PE->getResultExpr()) { SVal V = state->getSVal(Result, Pred->getLocationContext()); Bldr.generateNode(S, Pred, @@ -1945,14 +1965,14 @@ static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, const LocationContext *LCtx, ASTContext &Ctx) { - const Expr *Ex = dyn_cast(Condition); + const auto *Ex = dyn_cast(Condition); if (!Ex) return UnknownVal(); uint64_t bits = 0; bool bitsInit = false; - while (const CastExpr *CE = dyn_cast(Ex)) { + while (const auto *CE = dyn_cast(Ex)) { QualType T = CE->getType(); if (!T->isIntegralOrEnumerationType()) @@ -1980,7 +2000,7 @@ static SVal RecoverCastedSymbol(ProgramStateManager& StateMgr, #ifndef NDEBUG static const Stmt *getRightmostLeaf(const Stmt *Condition) { while (Condition) { - const BinaryOperator *BO = dyn_cast(Condition); + const auto *BO = dyn_cast(Condition); if (!BO || !BO->isLogicalOp()) { return Condition; } @@ -2006,10 +2026,10 @@ static const Stmt *getRightmostLeaf(const Stmt *Condition) { // space. static const Stmt *ResolveCondition(const Stmt *Condition, const CFGBlock *B) { - if (const Expr *Ex = dyn_cast(Condition)) + if (const auto *Ex = dyn_cast(Condition)) Condition = Ex->IgnoreParens(); - const BinaryOperator *BO = dyn_cast(Condition); + const auto *BO = dyn_cast(Condition); if (!BO || !BO->isLogicalOp()) return Condition; @@ -2057,7 +2077,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, return; } - if (const Expr *Ex = dyn_cast(Condition)) + if (const auto *Ex = dyn_cast(Condition)) Condition = Ex->IgnoreParens(); Condition = ResolveCondition(Condition, BldCtx.getBlock()); @@ -2073,10 +2093,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, return; BranchNodeBuilder builder(CheckersOutSet, Dst, BldCtx, DstT, DstF); - for (NodeBuilder::iterator I = CheckersOutSet.begin(), - E = CheckersOutSet.end(); E != I; ++I) { - ExplodedNode *PredI = *I; - + for (const auto PredI : CheckersOutSet) { if (PredI->isSink()) continue; @@ -2085,7 +2102,7 @@ void ExprEngine::processBranch(const Stmt *Condition, const Stmt *Term, if (X.isUnknownOrUndef()) { // Give it a chance to recover from unknown. - if (const Expr *Ex = dyn_cast(Condition)) { + if (const auto *Ex = dyn_cast(Condition)) { if (Ex->getType()->isIntegralOrEnumerationType()) { // Try to recover some path-sensitivity. Right now casts of symbolic // integers that promote their values are currently not tracked well. @@ -2142,13 +2159,13 @@ REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedGlobalsSet, void ExprEngine::processStaticInitializer(const DeclStmt *DS, NodeBuilderContext &BuilderCtx, ExplodedNode *Pred, - clang::ento::ExplodedNodeSet &Dst, + ExplodedNodeSet &Dst, const CFGBlock *DstT, const CFGBlock *DstF) { PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); currBldrCtx = &BuilderCtx; - const VarDecl *VD = cast(DS->getSingleDecl()); + const auto *VD = cast(DS->getSingleDecl()); ProgramStateRef state = Pred->getState(); bool initHasRun = state->contains(VD); BranchNodeBuilder builder(Pred, Dst, BuilderCtx, DstT, DstF); @@ -2166,7 +2183,6 @@ void ExprEngine::processStaticInitializer(const DeclStmt *DS, /// processIndirectGoto - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a computed goto jump. void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { - ProgramStateRef state = builder.getState(); SVal V = state->getSVal(builder.getTarget(), builder.getLocationContext()); @@ -2177,7 +2193,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { // (3) We have no clue about the label. Dispatch to all targets. // - typedef IndirectGotoNodeBuilder::iterator iterator; + using iterator = IndirectGotoNodeBuilder::iterator; if (Optional LV = V.getAs()) { const LabelDecl *L = LV->getLabel(); @@ -2203,7 +2219,7 @@ void ExprEngine::processIndirectGoto(IndirectGotoNodeBuilder &builder) { // This is really a catch-all. We don't support symbolics yet. // FIXME: Implement dispatch for symbolic pointers. - for (iterator I=builder.begin(), E=builder.end(); I != E; ++I) + for (iterator I = builder.begin(), E = builder.end(); I != E; ++I) builder.generateNode(I, state); } @@ -2273,10 +2289,8 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, removeDeadOnEndOfFunction(BC, Pred, AfterRemovedDead); // Notify checkers. - for (ExplodedNodeSet::iterator I = AfterRemovedDead.begin(), - E = AfterRemovedDead.end(); I != E; ++I) { - getCheckerManager().runCheckersForEndFunction(BC, Dst, *I, *this); - } + for (const auto I : AfterRemovedDead) + getCheckerManager().runCheckersForEndFunction(BC, Dst, I, *this); } else { getCheckerManager().runCheckersForEndFunction(BC, Dst, Pred, *this); } @@ -2287,7 +2301,8 @@ void ExprEngine::processEndOfFunction(NodeBuilderContext& BC, /// ProcessSwitch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a switch statement. void ExprEngine::processSwitch(SwitchNodeBuilder& builder) { - typedef SwitchNodeBuilder::iterator iterator; + using iterator = SwitchNodeBuilder::iterator; + ProgramStateRef state = builder.getState(); const Expr *CondE = builder.getCondition(); SVal CondV_untested = state->getSVal(CondE, builder.getLocationContext()); @@ -2376,7 +2391,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, ProgramStateRef state = Pred->getState(); const LocationContext *LCtx = Pred->getLocationContext(); - if (const VarDecl *VD = dyn_cast(D)) { + if (const auto *VD = dyn_cast(D)) { // C permits "extern void v", and if you cast the address to a valid type, // you can even do things with it. We simply pretend assert(Ex->isGLValue() || VD->getType()->isVoidType()); @@ -2426,13 +2441,13 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, ProgramPoint::PostLValueKind); return; } - if (const EnumConstantDecl *ED = dyn_cast(D)) { + if (const auto *ED = dyn_cast(D)) { assert(!Ex->isGLValue()); SVal V = svalBuilder.makeIntVal(ED->getInitVal()); Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); return; } - if (const FunctionDecl *FD = dyn_cast(D)) { + if (const auto *FD = dyn_cast(D)) { SVal V = svalBuilder.getFunctionPointer(FD); Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr, ProgramPoint::PostLValueKind); @@ -2509,7 +2524,6 @@ a vector and not a forbidden lvalue type"); /// VisitMemberExpr - Transfer function for member expressions. void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - // FIXME: Prechecks eventually go in ::Visit(). ExplodedNodeSet CheckedSet; getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this); @@ -2520,29 +2534,26 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, // Handle static member variables and enum constants accessed via // member syntax. if (isa(Member) || isa(Member)) { - for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); - I != E; ++I) { - VisitCommonDeclRefExpr(M, Member, *I, EvalSet); - } + for (const auto I : CheckedSet) + VisitCommonDeclRefExpr(M, Member, I, EvalSet); } else { StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx); ExplodedNodeSet Tmp; - for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); - I != E; ++I) { - ProgramStateRef state = (*I)->getState(); - const LocationContext *LCtx = (*I)->getLocationContext(); + for (const auto I : CheckedSet) { + ProgramStateRef state = I->getState(); + const LocationContext *LCtx = I->getLocationContext(); Expr *BaseExpr = M->getBase(); // Handle C++ method calls. - if (const CXXMethodDecl *MD = dyn_cast(Member)) { + if (const auto *MD = dyn_cast(Member)) { if (MD->isInstance()) state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); SVal MDVal = svalBuilder.getFunctionPointer(MD); state = state->BindExpr(M, LCtx, MDVal); - Bldr.generateNode(M, *I, state); + Bldr.generateNode(M, I, state); continue; } @@ -2550,7 +2561,7 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); SVal baseExprVal = state->getSVal(BaseExpr, LCtx); - FieldDecl *field = cast(Member); + const auto *field = cast(Member); SVal L = state->getLValue(field, baseExprVal); if (M->isGLValue() || M->getType()->isArrayType()) { @@ -2560,8 +2571,8 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, // pointers as soon as they are used. if (!M->isGLValue()) { assert(M->getType()->isArrayType()); - const ImplicitCastExpr *PE = - dyn_cast((*I)->getParentMap().getParentIgnoreParens(M)); + const auto *PE = + dyn_cast(I->getParentMap().getParentIgnoreParens(M)); if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) { llvm_unreachable("should always be wrapped in ArrayToPointerDecay"); } @@ -2574,11 +2585,11 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, L = UnknownVal(); } - Bldr.generateNode(M, *I, state->BindExpr(M, LCtx, L), nullptr, + Bldr.generateNode(M, I, state->BindExpr(M, LCtx, L), nullptr, ProgramPoint::PostLValueKind); } else { - Bldr.takeNodes(*I); - evalLoad(Tmp, M, M, *I, state, L); + Bldr.takeNodes(I); + evalLoad(Tmp, M, M, I, state, L); Bldr.addNodes(Tmp); } } @@ -2598,10 +2609,9 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred, ExplodedNodeSet AfterInvalidateSet; StmtNodeBuilder Bldr(AfterPreSet, AfterInvalidateSet, *currBldrCtx); - for (ExplodedNodeSet::iterator I = AfterPreSet.begin(), E = AfterPreSet.end(); - I != E; ++I) { - ProgramStateRef State = (*I)->getState(); - const LocationContext *LCtx = (*I)->getLocationContext(); + for (const auto I : AfterPreSet) { + ProgramStateRef State = I->getState(); + const LocationContext *LCtx = I->getLocationContext(); SmallVector ValuesToInvalidate; for (unsigned SI = 0, Count = AE->getNumSubExprs(); SI != Count; SI++) { @@ -2618,7 +2628,7 @@ void ExprEngine::VisitAtomicExpr(const AtomicExpr *AE, ExplodedNode *Pred, SVal ResultVal = UnknownVal(); State = State->BindExpr(AE, LCtx, ResultVal); - Bldr.generateNode(AE, *I, State, nullptr, + Bldr.generateNode(AE, I, State, nullptr, ProgramPoint::PostStmtKind); } @@ -2680,7 +2690,6 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, ArrayRef Regions, const CallEvent *Call, RegionAndSymbolInvalidationTraits &ITraits) { - if (!Invalidated || Invalidated->empty()) return State; @@ -2694,16 +2703,13 @@ ExprEngine::notifyCheckersOfPointerEscape(ProgramStateRef State, // If the symbols were invalidated by a call, we want to find out which ones // were invalidated directly due to being arguments to the call. InvalidatedSymbols SymbolsDirectlyInvalidated; - for (ArrayRef::iterator I = ExplicitRegions.begin(), - E = ExplicitRegions.end(); I != E; ++I) { - if (const SymbolicRegion *R = (*I)->StripCasts()->getAs()) + for (const auto I : ExplicitRegions) { + if (const SymbolicRegion *R = I->StripCasts()->getAs()) SymbolsDirectlyInvalidated.insert(R->getSymbol()); } InvalidatedSymbols SymbolsIndirectlyInvalidated; - for (InvalidatedSymbols::const_iterator I=Invalidated->begin(), - E = Invalidated->end(); I!=E; ++I) { - SymbolRef sym = *I; + for (const auto &sym : *Invalidated) { if (SymbolsDirectlyInvalidated.count(sym)) continue; SymbolsIndirectlyInvalidated.insert(sym); @@ -2727,7 +2733,6 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, SVal location, SVal Val, bool atDeclInit, const ProgramPoint *PP) { - const LocationContext *LC = Pred->getLocationContext(); PostStmt PS(StoreE, LC); if (!PP) @@ -2751,9 +2756,7 @@ void ExprEngine::evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, return; } - for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end(); - I!=E; ++I) { - ExplodedNode *PredI = *I; + for (const auto PredI : CheckedSet) { ProgramStateRef state = PredI->getState(); state = processPointerEscapedOnBind(state, location, Val, LC); @@ -2802,8 +2805,8 @@ void ExprEngine::evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, if (location.isUndef()) return; - for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) - evalBind(Dst, StoreE, *NI, location, Val, false); + for (const auto I : Tmp) + evalBind(Dst, StoreE, I, location, Val, false); } void ExprEngine::evalLoad(ExplodedNodeSet &Dst, @@ -2813,14 +2816,13 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, ProgramStateRef state, SVal location, const ProgramPointTag *tag, - QualType LoadTy) -{ + QualType LoadTy) { assert(!location.getAs() && "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 // referenced value. - if (const TypedValueRegion *TR = + if (const auto *TR = dyn_cast_or_null(location.getAsRegion())) { QualType ValTy = TR->getValueType(); @@ -2833,10 +2835,10 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, getContext().getPointerType(RT->getPointeeType())); // Perform the load from the referenced value. - for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end() ; I!=E; ++I) { - state = (*I)->getState(); - location = state->getSVal(BoundEx, (*I)->getLocationContext()); - evalLoadCommon(Dst, NodeEx, BoundEx, *I, state, location, tag, LoadTy); + for (const auto I : Tmp) { + state = I->getState(); + location = state->getSVal(BoundEx, I->getLocationContext()); + evalLoadCommon(Dst, NodeEx, BoundEx, I, state, location, tag, LoadTy); } return; } @@ -2866,9 +2868,9 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, return; // Proceed with the load. - for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI) { - state = (*NI)->getState(); - const LocationContext *LCtx = (*NI)->getLocationContext(); + for (const auto I : Tmp) { + state = I->getState(); + const LocationContext *LCtx = I->getLocationContext(); SVal V = UnknownVal(); if (location.isValid()) { @@ -2877,7 +2879,7 @@ void ExprEngine::evalLoadCommon(ExplodedNodeSet &Dst, V = state->getSVal(location.castAs(), LoadTy); } - Bldr.generateNode(NodeEx, *NI, state->BindExpr(BoundEx, LCtx, V), tag, + Bldr.generateNode(NodeEx, I, state->BindExpr(BoundEx, LCtx, V), tag, ProgramPoint::PostLoadKind); } } @@ -2934,8 +2936,7 @@ void ExprEngine::evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, const Expr *Ex) { StmtNodeBuilder Bldr(Src, Dst, *currBldrCtx); - for (ExplodedNodeSet::iterator I=Src.begin(), E=Src.end(); I!=E; ++I) { - ExplodedNode *Pred = *I; + for (const auto Pred : Src) { // Test if the previous node was as the same expression. This can happen // when the expression fails to evaluate to anything meaningful and // (as an optimization) we don't generate a node. @@ -2985,7 +2986,7 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred, for (const Expr *O : A->outputs()) { SVal X = state->getSVal(O, Pred->getLocationContext()); - assert (!X.getAs()); // Should be an Lval, or unknown, undef. + assert(!X.getAs()); // Should be an Lval, or unknown, undef. if (Optional LV = X.getAs()) state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext()); @@ -3009,16 +3010,15 @@ static ExprEngine* GraphPrintCheckerState; static SourceManager* GraphPrintSourceManager; namespace llvm { -template<> -struct DOTGraphTraits : - public DefaultDOTGraphTraits { - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} // FIXME: Since we do not cache error nodes in ExprEngine now, this does not // work. static std::string getNodeAttributes(const ExplodedNode *N, void*) { - return ""; + return {}; } // De-duplicate some source location pretty-printing. @@ -3033,7 +3033,6 @@ struct DOTGraphTraits : } static std::string getNodeLabel(const ExplodedNode *N, void*){ - std::string sbuf; llvm::raw_string_ostream Out(sbuf); @@ -3041,14 +3040,13 @@ struct DOTGraphTraits : ProgramPoint Loc = N->getLocation(); switch (Loc.getKind()) { - case ProgramPoint::BlockEntranceKind: { + case ProgramPoint::BlockEntranceKind: Out << "Block Entrance: B" << Loc.castAs().getBlock()->getBlockID(); break; - } case ProgramPoint::BlockExitKind: - assert (false); + assert(false); break; case ProgramPoint::CallEnterKind: @@ -3139,7 +3137,7 @@ struct DOTGraphTraits : const Stmt *Label = E.getDst()->getLabel(); if (Label) { - if (const CaseStmt *C = dyn_cast(Label)) { + if (const auto *C = dyn_cast(Label)) { Out << "\\lcase "; LangOptions LO; // FIXME. if (C->getLHS()) @@ -3153,7 +3151,7 @@ struct DOTGraphTraits : Out << ":"; } else { - assert (isa(Label)); + assert(isa(Label)); Out << "\\ldefault:"; } } @@ -3216,23 +3214,24 @@ struct DOTGraphTraits : return Out.str(); } }; -} // end llvm namespace + +} // namespace llvm #endif void ExprEngine::ViewGraph(bool trim) { #ifndef NDEBUG if (trim) { - std::vector Src; + std::vector Src; // Flush any outstanding reports to make sure we cover all the nodes. // This does not cause them to get displayed. - for (BugReporter::iterator I=BR.begin(), E=BR.end(); I!=E; ++I) - const_cast(*I)->FlushReports(BR); + for (const auto I : BR) + const_cast(I)->FlushReports(BR); // Iterate through the reports and get their nodes. for (BugReporter::EQClasses_iterator EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) { - ExplodedNode *N = const_cast(EI->begin()->getErrorNode()); + const auto *N = const_cast(EI->begin()->getErrorNode()); if (N) Src.push_back(N); }