From: Eugene Zelenko Date: Mon, 26 Feb 2018 23:15:52 +0000 (+0000) Subject: [StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use warnings... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f227f45a82a2d8529610fedb0c645c80fc9b9b4;p=clang [StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326146 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 49d159e37f..081718ea77 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -1,4 +1,4 @@ -//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===// +//===- CheckerManager.h - Static Analyzer Checker Manager -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,45 +16,56 @@ #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LangOptions.h" -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" -#include +#include "llvm/ADT/StringRef.h" #include namespace clang { - class Decl; - class Stmt; - class CallExpr; + +class AnalyzerOptions; +class CallExpr; +class CXXNewExpr; +class Decl; +class LocationContext; +class Stmt; +class TranslationUnitDecl; namespace ento { - class CheckerBase; - class CheckerRegistry; - class ExprEngine; - class AnalysisManager; - class BugReporter; - class CheckerContext; - class ObjCMethodCall; - class SVal; - class ExplodedNode; - class ExplodedNodeSet; - class ExplodedGraph; - class ProgramState; - class NodeBuilder; - struct NodeBuilderContext; - class MemRegion; - class SymbolReaper; + +class AnalysisManager; +class BugReporter; +class CallEvent; +class CheckerBase; +class CheckerContext; +class CheckerRegistry; +class ExplodedGraph; +class ExplodedNode; +class ExplodedNodeSet; +class ExprEngine; +class MemRegion; +struct NodeBuilderContext; +class ObjCMethodCall; +class RegionAndSymbolInvalidationTraits; +class SVal; +class SymbolReaper; template class CheckerFn; template class CheckerFn { - typedef RET (*Func)(void *, Ps...); + using Func = RET (*)(void *, Ps...); + Func Fn; + public: CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } + + CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) {} + RET operator()(Ps... ps) const { return Fn(Checker, ps...); } @@ -85,12 +96,15 @@ enum PointerEscapeKind { // name strings have a lifetime that keeps them alive at least until the path // diagnostics have been processed. class CheckName { - StringRef Name; friend class ::clang::ento::CheckerRegistry; + + StringRef Name; + explicit CheckName(StringRef Name) : Name(Name) {} public: CheckName() = default; + StringRef getName() const { return Name; } }; @@ -121,9 +135,9 @@ public: const LangOptions &getLangOpts() const { return LangOpts; } AnalyzerOptions &getAnalyzerOptions() { return AOptions; } - typedef CheckerBase *CheckerRef; - typedef const void *CheckerTag; - typedef CheckerFn CheckerDtor; + using CheckerRef = CheckerBase *; + using CheckerTag = const void *; + using CheckerDtor = CheckerFn; //===----------------------------------------------------------------------===// // registerChecker @@ -238,7 +252,6 @@ public: Eng); } - /// \brief Run checkers for visiting obj-c messages. void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, ExplodedNodeSet &Dst, @@ -368,7 +381,7 @@ public: const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, - RegionAndSymbolInvalidationTraits *ITraits); + RegionAndSymbolInvalidationTraits *ITraits); /// \brief Run checkers for handling assumptions on symbolic values. ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state, @@ -404,10 +417,11 @@ public: // Functions used by the registration mechanism, checkers should not touch // these directly. - typedef CheckerFn - CheckDeclFunc; + using CheckDeclFunc = + CheckerFn; + + using HandlesDeclFunc = bool (*)(const Decl *D); - typedef bool (*HandlesDeclFunc)(const Decl *D); void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); void _registerForBody(CheckDeclFunc checkfn); @@ -416,70 +430,66 @@ public: // Internal registration functions for path-sensitive checking. //===----------------------------------------------------------------------===// - typedef CheckerFn CheckStmtFunc; + using CheckStmtFunc = CheckerFn; - typedef CheckerFn - CheckObjCMessageFunc; + using CheckObjCMessageFunc = + CheckerFn; - typedef CheckerFn - CheckCallFunc; + using CheckCallFunc = + CheckerFn; - typedef CheckerFn - CheckLocationFunc; + using CheckLocationFunc = + CheckerFn; - typedef CheckerFn - CheckBindFunc; + using CheckBindFunc = + CheckerFn; - typedef CheckerFn - CheckEndAnalysisFunc; + using CheckEndAnalysisFunc = + CheckerFn; - typedef CheckerFn - CheckBeginFunctionFunc; + using CheckBeginFunctionFunc = CheckerFn; - typedef CheckerFn - CheckEndFunctionFunc; + using CheckEndFunctionFunc = CheckerFn; - typedef CheckerFn - CheckBranchConditionFunc; + using CheckBranchConditionFunc = + CheckerFn; - typedef CheckerFn - CheckNewAllocatorFunc; + using CheckNewAllocatorFunc = + CheckerFn; - typedef CheckerFn - CheckDeadSymbolsFunc; + using CheckDeadSymbolsFunc = + CheckerFn; - typedef CheckerFn CheckLiveSymbolsFunc; + using CheckLiveSymbolsFunc = CheckerFn; - typedef CheckerFn ExplicitRegions, - ArrayRef Regions, - const LocationContext *LCtx, - const CallEvent *Call)> - CheckRegionChangesFunc; + using CheckRegionChangesFunc = + CheckerFn ExplicitRegions, + ArrayRef Regions, + const LocationContext *LCtx, + const CallEvent *Call)>; - typedef CheckerFn - CheckPointerEscapeFunc; + using CheckPointerEscapeFunc = + CheckerFn; - typedef CheckerFn - EvalAssumeFunc; + using EvalAssumeFunc = + CheckerFn; - typedef CheckerFn - EvalCallFunc; + using EvalCallFunc = CheckerFn; + + using CheckEndOfTranslationUnit = + CheckerFn; - typedef CheckerFn - CheckEndOfTranslationUnit; + using HandlesStmtFunc = bool (*)(const Stmt *D); - typedef bool (*HandlesStmtFunc)(const Stmt *D); void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn); void _registerForPostStmt(CheckStmtFunc checkfn, @@ -526,8 +536,8 @@ public: // Internal registration functions for events. //===----------------------------------------------------------------------===// - typedef void *EventTag; - typedef CheckerFn CheckEventFunc; + using EventTag = void *; + using CheckEventFunc = CheckerFn; template void _registerListenerForEvent(CheckEventFunc checkfn) { @@ -547,8 +557,8 @@ public: if (I == Events.end()) return; const EventInfo &info = I->second; - for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) - info.Checkers[i](&event); + for (const auto Checker : info.Checkers) + Checker(&event); } //===----------------------------------------------------------------------===// @@ -574,8 +584,8 @@ private: std::vector BodyCheckers; - typedef SmallVector CachedDeclCheckers; - typedef llvm::DenseMap CachedDeclCheckersMapTy; + using CachedDeclCheckers = SmallVector; + using CachedDeclCheckersMapTy = llvm::DenseMap; CachedDeclCheckersMapTy CachedDeclCheckersMap; struct StmtCheckerInfo { @@ -585,8 +595,8 @@ private: }; std::vector StmtCheckers; - typedef SmallVector CachedStmtCheckers; - typedef llvm::DenseMap CachedStmtCheckersMapTy; + using CachedStmtCheckers = SmallVector; + using CachedStmtCheckersMapTy = llvm::DenseMap; CachedStmtCheckersMapTy CachedStmtCheckersMap; const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S, @@ -633,16 +643,17 @@ private: struct EventInfo { SmallVector Checkers; - bool HasDispatcher; - EventInfo() : HasDispatcher(false) { } + bool HasDispatcher = false; + + EventInfo() = default; }; - typedef llvm::DenseMap EventsTy; + using EventsTy = llvm::DenseMap; EventsTy Events; }; -} // end ento namespace +} // namespace ento -} // end clang namespace +} // namespace clang -#endif +#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index b82b404e5c..a55c43db6e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -1,4 +1,4 @@ -//=-- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -*- C++ -*-------==// +//===- ExplodedGraph.h - Local, Path-Sens. "Exploded Graph" -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,17 +19,25 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H -#include "clang/AST/Decl.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Analysis/Support/BumpVector.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include +#include #include #include #include @@ -37,6 +45,10 @@ namespace clang { class CFG; +class Decl; +class Expr; +class ParentMap; +class Stmt; namespace ento { @@ -52,13 +64,13 @@ class ExplodedGraph; // successors to it at any time after creating it. class ExplodedNode : public llvm::FoldingSetNode { - friend class ExplodedGraph; - friend class CoreEngine; - friend class NodeBuilder; friend class BranchNodeBuilder; + friend class CoreEngine; + friend class EndOfFunctionNodeBuilder; + friend class ExplodedGraph; friend class IndirectGotoNodeBuilder; + friend class NodeBuilder; friend class SwitchNodeBuilder; - friend class EndOfFunctionNodeBuilder; /// Efficiently stores a list of ExplodedNodes, or an optional flag. /// @@ -203,10 +215,10 @@ public: } // Iterators over successor and predecessor vertices. - typedef ExplodedNode* const * succ_iterator; - typedef const ExplodedNode* const * const_succ_iterator; - typedef ExplodedNode* const * pred_iterator; - typedef const ExplodedNode* const * const_pred_iterator; + using succ_iterator = ExplodedNode * const *; + using const_succ_iterator = const ExplodedNode * const *; + using pred_iterator = ExplodedNode * const *; + using const_pred_iterator = const ExplodedNode * const *; pred_iterator pred_begin() { return Preds.begin(); } pred_iterator pred_end() { return Preds.end(); } @@ -231,10 +243,10 @@ public: // For debugging. public: - class Auditor { public: virtual ~Auditor(); + virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) = 0; }; @@ -245,15 +257,15 @@ private: void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); } }; -typedef llvm::DenseMap - InterExplodedGraphMap; +using InterExplodedGraphMap = + llvm::DenseMap; class ExplodedGraph { protected: friend class CoreEngine; // Type definitions. - typedef std::vector NodeVector; + using NodeVector = std::vector; /// The roots of the simulation graph. Usually there will be only /// one, but clients are free to establish multiple subgraphs within a single @@ -273,7 +285,7 @@ protected: BumpVectorContext BVC; /// NumNodes - The number of nodes in the graph. - unsigned NumNodes; + unsigned NumNodes = 0; /// A list of recently allocated nodes that can potentially be recycled. NodeVector ChangedNodes; @@ -284,12 +296,14 @@ protected: /// Determines how often nodes are reclaimed. /// /// If this is 0, nodes will never be reclaimed. - unsigned ReclaimNodeInterval; + unsigned ReclaimNodeInterval = 0; /// Counter to determine when to reclaim nodes. unsigned ReclaimCounter; public: + ExplodedGraph(); + ~ExplodedGraph(); /// \brief Retrieve the node associated with a (Location,State) pair, /// where the 'Location' is a ProgramPoint in the CFG. If no node for @@ -323,10 +337,6 @@ public: return V; } - ExplodedGraph(); - - ~ExplodedGraph(); - unsigned num_roots() const { return Roots.size(); } unsigned num_eops() const { return EndNodes.size(); } @@ -336,14 +346,14 @@ public: void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); } // Iterators. - typedef ExplodedNode NodeTy; - typedef llvm::FoldingSet AllNodesTy; - typedef NodeVector::iterator roots_iterator; - typedef NodeVector::const_iterator const_roots_iterator; - typedef NodeVector::iterator eop_iterator; - typedef NodeVector::const_iterator const_eop_iterator; - typedef AllNodesTy::iterator node_iterator; - typedef AllNodesTy::const_iterator const_node_iterator; + using NodeTy = ExplodedNode; + using AllNodesTy = llvm::FoldingSet; + using roots_iterator = NodeVector::iterator; + using const_roots_iterator = NodeVector::const_iterator; + using eop_iterator = NodeVector::iterator; + using const_eop_iterator = NodeVector::const_iterator; + using node_iterator = AllNodesTy::iterator; + using const_node_iterator = AllNodesTy::const_iterator; node_iterator nodes_begin() { return Nodes.begin(); } @@ -372,7 +382,7 @@ public: llvm::BumpPtrAllocator & getAllocator() { return BVC.getAllocator(); } BumpVectorContext &getNodeAllocator() { return BVC; } - typedef llvm::DenseMap NodeMap; + using NodeMap = llvm::DenseMap; /// Creates a trimmed version of the graph that only contains paths leading /// to the given nodes. @@ -409,29 +419,30 @@ private: }; class ExplodedNodeSet { - typedef llvm::SmallSetVector ImplTy; + using ImplTy = llvm::SmallSetVector; ImplTy Impl; public: ExplodedNodeSet(ExplodedNode *N) { - assert (N && !static_cast(N)->isSink()); + assert(N && !static_cast(N)->isSink()); Impl.insert(N); } - ExplodedNodeSet() {} + ExplodedNodeSet() = default; - inline void Add(ExplodedNode *N) { + void Add(ExplodedNode *N) { if (N && !static_cast(N)->isSink()) Impl.insert(N); } - typedef ImplTy::iterator iterator; - typedef ImplTy::const_iterator const_iterator; + using iterator = ImplTy::iterator; + using const_iterator = ImplTy::const_iterator; unsigned size() const { return Impl.size(); } bool empty() const { return Impl.empty(); } bool erase(ExplodedNode *N) { return Impl.remove(N); } void clear() { Impl.clear(); } + void insert(const ExplodedNodeSet &S) { assert(&S != this); if (empty()) @@ -440,24 +451,25 @@ public: Impl.insert(S.begin(), S.end()); } - inline iterator begin() { return Impl.begin(); } - inline iterator end() { return Impl.end(); } + iterator begin() { return Impl.begin(); } + iterator end() { return Impl.end(); } - inline const_iterator begin() const { return Impl.begin(); } - inline const_iterator end() const { return Impl.end(); } + const_iterator begin() const { return Impl.begin(); } + const_iterator end() const { return Impl.end(); } }; -} // end GR namespace +} // namespace ento -} // end clang namespace +} // namespace clang // GraphTraits namespace llvm { + template<> struct GraphTraits { - typedef clang::ento::ExplodedNode *NodeRef; - typedef clang::ento::ExplodedNode::succ_iterator ChildIteratorType; - typedef llvm::df_iterator nodes_iterator; + using NodeRef = clang::ento::ExplodedNode *; + using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator; + using nodes_iterator = llvm::df_iterator; static NodeRef getEntryNode(NodeRef N) { return N; } @@ -471,9 +483,9 @@ namespace llvm { }; template<> struct GraphTraits { - typedef const clang::ento::ExplodedNode *NodeRef; - typedef clang::ento::ExplodedNode::const_succ_iterator ChildIteratorType; - typedef llvm::df_iterator nodes_iterator; + using NodeRef = const clang::ento::ExplodedNode *; + using ChildIteratorType = clang::ento::ExplodedNode::const_succ_iterator; + using nodes_iterator = llvm::df_iterator; static NodeRef getEntryNode(NodeRef N) { return N; } @@ -486,6 +498,6 @@ namespace llvm { static nodes_iterator nodes_end(NodeRef N) { return df_end(N); } }; -} // end llvm namespace +} // namespace llvm -#endif +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp index f3de2e4050..882e4f9e35 100644 --- a/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -1,4 +1,4 @@ -//===--- CheckerManager.cpp - Static Analyzer Checker Manager -------------===// +//===- CheckerManager.cpp - Static Analyzer Checker Manager ---------------===// // // The LLVM Compiler Infrastructure // @@ -13,10 +13,20 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/Stmt.h" #include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include +#include using namespace clang; using namespace ento; @@ -43,9 +53,9 @@ void CheckerManager::finishedCheckerRegistration() { #ifndef NDEBUG // Make sure that for every event that has listeners, there is at least // one dispatcher registered for it. - for (llvm::DenseMap::iterator - I = Events.begin(), E = Events.end(); I != E; ++I) - assert(I->second.HasDispatcher && "No dispatcher registered for an event"); + for (const auto &Event : Events) + assert(Event.second.HasDispatcher && + "No dispatcher registered for an event"); #endif } @@ -65,25 +75,22 @@ void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, } else { // Find the checkers that should run for this Decl and cache them. checkers = &CachedDeclCheckersMap[DeclKind]; - for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) { - DeclCheckerInfo &info = DeclCheckers[i]; + for (const auto &info : DeclCheckers) if (info.IsForDeclFn(D)) checkers->push_back(info.CheckFn); - } } assert(checkers); - for (CachedDeclCheckers::iterator - I = checkers->begin(), E = checkers->end(); I != E; ++I) - (*I)(D, mgr, BR); + for (const auto checker : *checkers) + checker(D, mgr, BR); } void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, BugReporter &BR) { assert(D && D->hasBody()); - for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i) - BodyCheckers[i](D, mgr, BR); + for (const auto BodyChecker : BodyCheckers) + BodyChecker(D, mgr, BR); } //===----------------------------------------------------------------------===// @@ -118,10 +125,8 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, } NodeBuilder B(*PrevSet, *CurrSet, BldrCtx); - for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end(); - NI != NE; ++NI) { - checkCtx.runChecker(*I, B, *NI); - } + for (const auto &NI : *PrevSet) + checkCtx.runChecker(*I, B, NI); // If all the produced transitions are sinks, stop. if (CurrSet->empty()) @@ -133,21 +138,23 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, } namespace { + struct CheckStmtContext { - typedef SmallVectorImpl CheckersTy; + using CheckersTy = SmallVectorImpl; + bool IsPreVisit; const CheckersTy &Checkers; const Stmt *S; ExprEngine &Eng; bool WasInlined; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckStmtContext(bool isPreVisit, const CheckersTy &checkers, const Stmt *s, ExprEngine &eng, bool wasInlined = false) - : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng), - WasInlined(wasInlined) {} + : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng), + WasInlined(wasInlined) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckStmtFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -160,7 +167,8 @@ namespace { checkFn(S, C); } }; -} + +} // namespace /// \brief Run checkers for visiting Stmts. void CheckerManager::runCheckersForStmt(bool isPreVisit, @@ -175,8 +183,9 @@ void CheckerManager::runCheckersForStmt(bool isPreVisit, } namespace { + struct CheckObjCMessageContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; ObjCMessageVisitKind Kind; bool WasInlined; @@ -184,19 +193,18 @@ namespace { const ObjCMethodCall &Msg; ExprEngine &Eng; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckObjCMessageContext(ObjCMessageVisitKind visitKind, const CheckersTy &checkers, const ObjCMethodCall &msg, ExprEngine &eng, bool wasInlined) - : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), - Msg(msg), Eng(eng) { } + : Kind(visitKind), WasInlined(wasInlined), Checkers(checkers), Msg(msg), + Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { - bool IsPreVisit; switch (Kind) { @@ -215,7 +223,8 @@ namespace { checkFn(*Msg.cloneWithState(Pred->getState()), C); } }; -} + +} // namespace /// \brief Run checkers for visiting obj-c messages. void CheckerManager::runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, @@ -242,24 +251,27 @@ CheckerManager::getObjCMessageCheckers(ObjCMessageVisitKind Kind) { } llvm_unreachable("Unknown Kind"); } + namespace { + // FIXME: This has all the same signatures as CheckObjCMessageContext. // Is there a way we can merge the two? struct CheckCallContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + bool IsPreVisit, WasInlined; const CheckersTy &Checkers; const CallEvent &Call; ExprEngine &Eng; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckCallContext(bool isPreVisit, const CheckersTy &checkers, const CallEvent &call, ExprEngine &eng, bool wasInlined) - : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers), - Call(call), Eng(eng) { } + : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers), + Call(call), Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckCallFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -269,7 +281,8 @@ namespace { checkFn(*Call.cloneWithState(Pred->getState()), C); } }; -} + +} // namespace /// \brief Run checkers for visiting an abstract call event. void CheckerManager::runCheckersForCallEvent(bool isPreVisit, @@ -286,8 +299,10 @@ void CheckerManager::runCheckersForCallEvent(bool isPreVisit, } namespace { + struct CheckLocationContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; SVal Loc; bool IsLoad; @@ -295,15 +310,15 @@ namespace { const Stmt *BoundEx; ExprEngine &Eng; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckLocationContext(const CheckersTy &checkers, SVal loc, bool isLoad, const Stmt *NodeEx, const Stmt *BoundEx, ExprEngine &eng) - : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx), - BoundEx(BoundEx), Eng(eng) {} + : Checkers(checkers), Loc(loc), IsLoad(isLoad), NodeEx(NodeEx), + BoundEx(BoundEx), Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckLocationFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -317,7 +332,8 @@ namespace { checkFn(Loc, IsLoad, BoundEx, C); } }; -} + +} // namespace /// \brief Run checkers for load/store of a location. @@ -333,8 +349,10 @@ void CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst, } namespace { + struct CheckBindContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; SVal Loc; SVal Val; @@ -342,13 +360,13 @@ namespace { ExprEngine &Eng; const ProgramPoint &PP; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckBindContext(const CheckersTy &checkers, SVal loc, SVal val, const Stmt *s, ExprEngine &eng, const ProgramPoint &pp) - : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {} + : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng), PP(pp) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckBindFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -358,7 +376,8 @@ namespace { checkFn(Loc, Val, S, C); } }; -} + +} // namespace /// \brief Run checkers for binding of a value to a location. void CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, @@ -373,24 +392,26 @@ void CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, void CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng) { - for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i) - EndAnalysisCheckers[i](G, BR, Eng); + for (const auto EndAnalysisChecker : EndAnalysisCheckers) + EndAnalysisChecker(G, BR, Eng); } namespace { + struct CheckBeginFunctionContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; ExprEngine &Eng; const ProgramPoint &PP; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckBeginFunctionContext(const CheckersTy &Checkers, ExprEngine &Eng, const ProgramPoint &PP) : Checkers(Checkers), Eng(Eng), PP(PP) {} + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + void runChecker(CheckerManager::CheckBeginFunctionFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { const ProgramPoint &L = PP.withTag(checkFn.Checker); @@ -399,7 +420,8 @@ struct CheckBeginFunctionContext { checkFn(C); } }; -} + +} // namespace void CheckerManager::runCheckersForBeginFunction(ExplodedNodeSet &Dst, const BlockEdge &L, @@ -418,14 +440,11 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, ExplodedNode *Pred, ExprEngine &Eng) { - // We define the builder outside of the loop bacause if at least one checkers // creates a sucsessor for Pred, we do not need to generate an // autotransition for it. NodeBuilder Bldr(Pred, Dst, BC); - for (unsigned i = 0, e = EndFunctionCheckers.size(); i != e; ++i) { - CheckEndFunctionFunc checkFn = EndFunctionCheckers[i]; - + for (const auto checkFn : EndFunctionCheckers) { const ProgramPoint &L = BlockEntrance(BC.Block, Pred->getLocationContext(), checkFn.Checker); @@ -435,18 +454,20 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC, } namespace { + struct CheckBranchConditionContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; const Stmt *Condition; ExprEngine &Eng; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckBranchConditionContext(const CheckersTy &checkers, const Stmt *Cond, ExprEngine &eng) - : Checkers(checkers), Condition(Cond), Eng(eng) {} + : Checkers(checkers), Condition(Cond), Eng(eng) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -456,7 +477,8 @@ namespace { checkFn(Condition, C); } }; -} + +} // namespace /// \brief Run checkers for branch condition. void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, @@ -470,22 +492,24 @@ void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, } namespace { + struct CheckNewAllocatorContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; const CXXNewExpr *NE; SVal Target; bool WasInlined; ExprEngine &Eng; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckNewAllocatorContext(const CheckersTy &Checkers, const CXXNewExpr *NE, SVal Target, bool WasInlined, ExprEngine &Eng) : Checkers(Checkers), NE(NE), Target(Target), WasInlined(WasInlined), Eng(Eng) {} + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } + void runChecker(CheckerManager::CheckNewAllocatorFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { ProgramPoint L = PostAllocatorCall(NE, Pred->getLocationContext()); @@ -493,7 +517,8 @@ namespace { checkFn(NE, Target, C); } }; -} + +} // namespace void CheckerManager::runCheckersForNewAllocator( const CXXNewExpr *NE, SVal Target, ExplodedNodeSet &Dst, ExplodedNode *Pred, @@ -507,26 +532,28 @@ void CheckerManager::runCheckersForNewAllocator( /// \brief Run checkers for live symbols. void CheckerManager::runCheckersForLiveSymbols(ProgramStateRef state, SymbolReaper &SymReaper) { - for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i) - LiveSymbolsCheckers[i](state, SymReaper); + for (const auto LiveSymbolsChecker : LiveSymbolsCheckers) + LiveSymbolsChecker(state, SymReaper); } namespace { + struct CheckDeadSymbolsContext { - typedef std::vector CheckersTy; + using CheckersTy = std::vector; + const CheckersTy &Checkers; SymbolReaper &SR; const Stmt *S; ExprEngine &Eng; ProgramPoint::Kind ProgarmPointKind; - CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } - CheckersTy::const_iterator checkers_end() { return Checkers.end(); } - CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr, const Stmt *s, ExprEngine &eng, ProgramPoint::Kind K) - : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) { } + : Checkers(checkers), SR(sr), S(s), Eng(eng), ProgarmPointKind(K) {} + + CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); } + CheckersTy::const_iterator checkers_end() { return Checkers.end(); } void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { @@ -540,7 +567,8 @@ namespace { checkFn(SR, C); } }; -} + +} // namespace /// \brief Run checkers for dead symbols. void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst, @@ -561,14 +589,13 @@ CheckerManager::runCheckersForRegionChanges(ProgramStateRef state, ArrayRef Regions, const LocationContext *LCtx, const CallEvent *Call) { - for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) { + for (const auto RegionChangesChecker : RegionChangesCheckers) { // If any checker declares the state infeasible (or if it starts that way), // bail out. if (!state) return nullptr; - state = RegionChangesCheckers[i](state, invalidated, - ExplicitRegions, Regions, - LCtx, Call); + state = RegionChangesChecker(state, invalidated, ExplicitRegions, Regions, + LCtx, Call); } return state; } @@ -584,13 +611,13 @@ CheckerManager::runCheckersForPointerEscape(ProgramStateRef State, (Kind != PSK_DirectEscapeOnCall && Kind != PSK_IndirectEscapeOnCall)) && "Call must not be NULL when escaping on call"); - for (unsigned i = 0, e = PointerEscapeCheckers.size(); i != e; ++i) { - // If any checker declares the state infeasible (or if it starts that - // way), bail out. - if (!State) - return nullptr; - State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, ETraits); - } + for (const auto PointerEscapeChecker : PointerEscapeCheckers) { + // If any checker declares the state infeasible (or if it starts that + // way), bail out. + if (!State) + return nullptr; + State = PointerEscapeChecker(State, Escaped, Call, Kind, ETraits); + } return State; } @@ -598,12 +625,12 @@ CheckerManager::runCheckersForPointerEscape(ProgramStateRef State, ProgramStateRef CheckerManager::runCheckersForEvalAssume(ProgramStateRef state, SVal Cond, bool Assumption) { - for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) { + for (const auto EvalAssumeChecker : EvalAssumeCheckers) { // If any checker declares the state infeasible (or if it starts that way), // bail out. if (!state) return nullptr; - state = EvalAssumeCheckers[i](state, Cond, Assumption); + state = EvalAssumeChecker(state, Cond, Assumption); } return state; } @@ -615,27 +642,24 @@ void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst, const CallEvent &Call, ExprEngine &Eng) { const CallExpr *CE = cast(Call.getOriginExpr()); - for (ExplodedNodeSet::iterator - NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) { - ExplodedNode *Pred = *NI; + for (const auto Pred : Src) { bool anyEvaluated = false; ExplodedNodeSet checkDst; NodeBuilder B(Pred, checkDst, Eng.getBuilderContext()); // Check if any of the EvalCall callbacks can evaluate the call. - for (std::vector::iterator - EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end(); - EI != EE; ++EI) { + for (const auto EvalCallChecker : EvalCallCheckers) { ProgramPoint::Kind K = ProgramPoint::PostStmtKind; - const ProgramPoint &L = ProgramPoint::getProgramPoint(CE, K, - Pred->getLocationContext(), EI->Checker); + const ProgramPoint &L = + ProgramPoint::getProgramPoint(CE, K, Pred->getLocationContext(), + EvalCallChecker.Checker); bool evaluated = false; { // CheckerContext generates transitions(populates checkDest) on // destruction, so introduce the scope to make sure it gets properly // populated. CheckerContext C(B, Eng, Pred, L); - evaluated = (*EI)(CE, C); + evaluated = EvalCallChecker(CE, C); } assert(!(evaluated && anyEvaluated) && "There are more than one checkers evaluating the call"); @@ -661,16 +685,15 @@ void CheckerManager::runCheckersOnEndOfTranslationUnit( const TranslationUnitDecl *TU, AnalysisManager &mgr, BugReporter &BR) { - for (unsigned i = 0, e = EndOfTranslationUnitCheckers.size(); i != e; ++i) - EndOfTranslationUnitCheckers[i](TU, mgr, BR); + for (const auto EndOfTranslationUnitChecker : EndOfTranslationUnitCheckers) + EndOfTranslationUnitChecker(TU, mgr, BR); } void CheckerManager::runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) { - for (llvm::DenseMap::iterator - I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I) - I->second->printState(Out, State, NL, Sep); + for (const auto &CheckerTag : CheckerTags) + CheckerTag.second->printState(Out, State, NL, Sep); } //===----------------------------------------------------------------------===// @@ -696,6 +719,7 @@ void CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn, StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true }; StmtCheckers.push_back(info); } + void CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn) { StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false }; @@ -799,15 +823,13 @@ CheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) { // Find the checkers that should run for this Stmt and cache them. CachedStmtCheckers &Checkers = CachedStmtCheckersMap[Key]; - for (unsigned i = 0, e = StmtCheckers.size(); i != e; ++i) { - StmtCheckerInfo &Info = StmtCheckers[i]; + for (const auto &Info : StmtCheckers) if (Info.IsPreVisit == isPreVisit && Info.IsForStmtFn(S)) Checkers.push_back(Info.CheckFn); - } return Checkers; } CheckerManager::~CheckerManager() { - for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i) - CheckerDtors[i](); + for (const auto CheckerDtor : CheckerDtors) + CheckerDtor(); } diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 3bc8e09333..ece103d9d0 100644 --- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -1,4 +1,4 @@ -//=-- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -*- C++ -*------=// +//===- ExplodedGraph.cpp - Local, Path-Sens. "Exploded Graph" -------------===// // // The LLVM Compiler Infrastructure // @@ -13,13 +13,24 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/ParentMap.h" #include "clang/AST/Stmt.h" +#include "clang/Analysis/ProgramPoint.h" +#include "clang/Analysis/Support/BumpVector.h" +#include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Casting.h" +#include +#include using namespace clang; using namespace ento; @@ -29,7 +40,7 @@ using namespace ento; //===----------------------------------------------------------------------===// // An out of line virtual method to provide a home for the class vtable. -ExplodedNode::Auditor::~Auditor() {} +ExplodedNode::Auditor::~Auditor() = default; #ifndef NDEBUG static ExplodedNode::Auditor* NodeAuditor = nullptr; @@ -45,10 +56,9 @@ void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) { // Cleanup. //===----------------------------------------------------------------------===// -ExplodedGraph::ExplodedGraph() - : NumNodes(0), ReclaimNodeInterval(0) {} +ExplodedGraph::ExplodedGraph() = default; -ExplodedGraph::~ExplodedGraph() {} +ExplodedGraph::~ExplodedGraph() = default; //===----------------------------------------------------------------------===// // Node reclamation. @@ -187,12 +197,9 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() { return; ReclaimCounter = ReclaimNodeInterval; - for (NodeVector::iterator it = ChangedNodes.begin(), et = ChangedNodes.end(); - it != et; ++it) { - ExplodedNode *node = *it; + for (const auto node : ChangedNodes) if (shouldCollect(node)) collectNode(node); - } ChangedNodes.clear(); } @@ -210,11 +217,11 @@ void ExplodedGraph::reclaimRecentlyAllocatedNodes() { // 2. The group is empty, in which case the storage value is null. // 3. The group contains a single node. // 4. The group contains more than one node. -typedef BumpVector ExplodedNodeVector; -typedef llvm::PointerUnion GroupStorage; +using ExplodedNodeVector = BumpVector; +using GroupStorage = llvm::PointerUnion; void ExplodedNode::addPredecessor(ExplodedNode *V, ExplodedGraph &G) { - assert (!V->isSink()); + assert(!V->isSink()); Preds.addNode(V, G); V->Succs.addNode(this, G); #ifndef NDEBUG @@ -346,25 +353,22 @@ std::unique_ptr ExplodedGraph::trim(ArrayRef Sinks, InterExplodedGraphMap *ForwardMap, InterExplodedGraphMap *InverseMap) const { - if (Nodes.empty()) return nullptr; - typedef llvm::DenseSet Pass1Ty; + using Pass1Ty = llvm::DenseSet; Pass1Ty Pass1; - typedef InterExplodedGraphMap Pass2Ty; + using Pass2Ty = InterExplodedGraphMap; InterExplodedGraphMap Pass2Scratch; Pass2Ty &Pass2 = ForwardMap ? *ForwardMap : Pass2Scratch; SmallVector WL1, WL2; // ===- Pass 1 (reverse DFS) -=== - for (ArrayRef::iterator I = Sinks.begin(), E = Sinks.end(); - I != E; ++I) { - if (*I) - WL1.push_back(*I); - } + for (const auto Sink : Sinks) + if (Sink) + WL1.push_back(Sink); // Process the first worklist until it is empty. while (!WL1.empty()) { @@ -445,4 +449,3 @@ ExplodedGraph::trim(ArrayRef Sinks, return G; } - diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index c6e397fa6a..b4e73c81e5 100644 --- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -1,4 +1,4 @@ -//===--- HTMLDiagnostics.cpp - HTML Diagnostics for Paths ----*- C++ -*-===// +//===- HTMLDiagnostics.cpp - HTML Diagnostics for Paths -------------------===// // // The LLVM Compiler Infrastructure // @@ -11,26 +11,43 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/Stmt.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/Token.h" #include "clang/Rewrite/Core/HTMLRewrite.h" #include "clang/Rewrite/Core/Rewriter.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/IssueHash.h" #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include +#include #include +#include #include #include +#include +#include +#include +#include using namespace clang; using namespace ento; @@ -43,15 +60,19 @@ namespace { class HTMLDiagnostics : public PathDiagnosticConsumer { std::string Directory; - bool createdDir, noDir; + bool createdDir = false; + bool noDir = false; const Preprocessor &PP; AnalyzerOptions &AnalyzerOpts; const bool SupportsCrossFileDiagnostics; + public: HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, const Preprocessor &pp, - bool supportsMultipleFiles); + bool supportsMultipleFiles) + : Directory(prefix), PP(pp), AnalyzerOpts(AnalyzerOpts), + SupportsCrossFileDiagnostics(supportsMultipleFiles) {} ~HTMLDiagnostics() override { FlushDiagnostics(nullptr); } @@ -98,23 +119,11 @@ public: std::string generateKeyboardNavigationJavascript(); private: - /// \return Javascript for displaying shortcuts help; std::string showHelpJavascript(); }; -} // end anonymous namespace - -HTMLDiagnostics::HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, - const std::string& prefix, - const Preprocessor &pp, - bool supportsMultipleFiles) - : Directory(prefix), - createdDir(false), - noDir(false), - PP(pp), - AnalyzerOpts(AnalyzerOpts), - SupportsCrossFileDiagnostics(supportsMultipleFiles) {} +} // namespace void ento::createHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C, @@ -137,24 +146,19 @@ void ento::createHTMLSingleFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts, void HTMLDiagnostics::FlushDiagnosticsImpl( std::vector &Diags, FilesMade *filesMade) { - for (std::vector::iterator it = Diags.begin(), - et = Diags.end(); it != et; ++it) { - ReportDiag(**it, filesMade); - } + for (const auto Diag : Diags) + ReportDiag(*Diag, filesMade); } void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, FilesMade *filesMade) { - // Create the HTML directory if it is missing. if (!createdDir) { createdDir = true; if (std::error_code ec = llvm::sys::fs::create_directories(Directory)) { llvm::errs() << "warning: could not create directory '" << Directory << "': " << ec.message() << '\n'; - noDir = true; - return; } } @@ -181,7 +185,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, SmallString<128> declName("unknown"); int offsetDecl = 0; if (const Decl *DeclWithIssue = D.getDeclWithIssue()) { - if (const NamedDecl *ND = dyn_cast(DeclWithIssue)) + if (const auto *ND = dyn_cast(DeclWithIssue)) declName = ND->getDeclName().getAsString(); if (const Stmt *Body = DeclWithIssue->getBody()) { @@ -219,7 +223,6 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, << "': " << EC.message() << '\n'; return; } - } else { int i = 1; std::error_code EC; @@ -260,7 +263,6 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R, const SourceManager& SMgr, const PathPieces& path, const char *declName) { - // Rewrite source files as HTML for every new file the path crosses std::vector FileIDs; for (auto I : path) { @@ -316,7 +318,7 @@ std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R, const RewriteBuffer *Buf = R.getRewriteBufferFor(FileIDs[0]); if (!Buf) - return ""; + return {}; // Add CSS, header, and footer. const FileEntry* Entry = SMgr.getFileEntryForID(FileIDs[0]); @@ -335,7 +337,6 @@ static void serializeExecutedLines( const PathDiagnostic &D, const PathPieces &path, llvm::raw_string_ostream &os) { - // Copy executed lines from path diagnostics. std::map> ExecutedLines; for (auto I = D.executedLines_begin(), @@ -501,8 +502,8 @@ void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R, // Output any other meta data. - for (PathDiagnostic::meta_iterator I=D.meta_begin(), E=D.meta_end(); - I!=E; ++I) { + for (PathDiagnostic::meta_iterator I = D.meta_begin(), E = D.meta_end(); + I != E; ++I) { os << "" << html::EscapeText(*I) << "\n"; } @@ -613,9 +614,6 @@ window.addEventListener("keydown", function (event) { )<<<"; } - - - void HTMLDiagnostics::RewriteFile(Rewriter &R, const SourceManager& SMgr, const PathPieces& path, FileID FID) { // Process the path. @@ -660,7 +658,6 @@ void HTMLDiagnostics::RewriteFile(Rewriter &R, const SourceManager& SMgr, void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, const PathDiagnosticPiece& P, unsigned num, unsigned max) { - // For now, just draw a box above the line in question, and emit the // warning. FullSourceLoc Pos = P.getLocation().asLocation(); @@ -800,9 +797,7 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, os << ""; } - if (const PathDiagnosticMacroPiece *MP = - dyn_cast(&P)) { - + if (const auto *MP = dyn_cast(&P)) { os << "Within the expansion of the macro '"; // Get the name of the macro by relexing it. @@ -873,10 +868,8 @@ void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID, // Now highlight the ranges. ArrayRef Ranges = P.getRanges(); - for (ArrayRef::iterator I = Ranges.begin(), - E = Ranges.end(); I != E; ++I) { - HighlightRange(R, LPosInfo.first, *I); - } + for (const auto &Range : Ranges) + HighlightRange(R, LPosInfo.first, Range); } static void EmitAlphaCounter(raw_ostream &os, unsigned n) { @@ -892,18 +885,13 @@ static void EmitAlphaCounter(raw_ostream &os, unsigned n) { unsigned HTMLDiagnostics::ProcessMacroPiece(raw_ostream &os, const PathDiagnosticMacroPiece& P, unsigned num) { - - for (PathPieces::const_iterator I = P.subPieces.begin(), E=P.subPieces.end(); - I!=E; ++I) { - - if (const PathDiagnosticMacroPiece *MP = - dyn_cast(I->get())) { + for (const auto &subPiece : P.subPieces) { + if (const auto *MP = dyn_cast(subPiece.get())) { num = ProcessMacroPiece(os, *MP, num); continue; } - if (PathDiagnosticEventPiece *EP = - dyn_cast(I->get())) { + if (const auto *EP = dyn_cast(subPiece.get())) { os << "
" ""