diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend')
4 files changed, 83 insertions, 138 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 9efe997..f0dd274 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -11,15 +11,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "AnalysisConsumer" - -#include "AnalysisConsumer.h" +#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/DataRecursiveASTVisitor.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CallGraph.h" @@ -36,7 +34,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" #include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -45,12 +42,15 @@ #include "llvm/Support/Program.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" +#include <memory> #include <queue> using namespace clang; using namespace ento; using llvm::SmallPtrSet; +#define DEBUG_TYPE "AnalysisConsumer" + static ExplodedNode::Auditor* CreateUbiViz(); STATISTIC(NumFunctionTopLevel, "The # of functions at top level."); @@ -90,12 +90,12 @@ public: ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) : Diag(Diag), IncludePath(false) {} virtual ~ClangDiagPathDiagConsumer() {} - virtual StringRef getName() const { return "ClangDiags"; } + StringRef getName() const override { return "ClangDiags"; } - virtual bool supportsLogicalOpControlFlow() const { return true; } - virtual bool supportsCrossFileDiagnostics() const { return true; } + bool supportsLogicalOpControlFlow() const override { return true; } + bool supportsCrossFileDiagnostics() const override { return true; } - virtual PathGenerationScheme getGenerationScheme() const { + PathGenerationScheme getGenerationScheme() const override { return IncludePath ? Minimal : None; } @@ -103,35 +103,17 @@ public: IncludePath = true; } - void emitDiag(SourceLocation L, unsigned DiagID, - ArrayRef<SourceRange> Ranges) { - DiagnosticBuilder DiagBuilder = Diag.Report(L, DiagID); - - for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); - I != E; ++I) { - DiagBuilder << *I; - } - } - void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags, - FilesMade *filesMade) { + FilesMade *filesMade) override { + unsigned WarnID = Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0"); + unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0"); + for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(), E = Diags.end(); I != E; ++I) { const PathDiagnostic *PD = *I; - StringRef desc = PD->getShortDescription(); - SmallString<512> TmpStr; - llvm::raw_svector_ostream Out(TmpStr); - for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) { - if (*I == '%') - Out << "%%"; - else - Out << *I; - } - Out.flush(); - unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning, - TmpStr); - SourceLocation L = PD->getLocation().asLocation(); - emitDiag(L, ErrorDiag, PD->path.back()->getRanges()); + SourceLocation WarnLoc = PD->getLocation().asLocation(); + Diag.Report(WarnLoc, WarnID) << PD->getShortDescription() + << PD->path.back()->getRanges(); if (!IncludePath) continue; @@ -140,11 +122,9 @@ public: for (PathPieces::const_iterator PI = FlatPath.begin(), PE = FlatPath.end(); PI != PE; ++PI) { - unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, - (*PI)->getString()); - SourceLocation NoteLoc = (*PI)->getLocation().asLocation(); - emitDiag(NoteLoc, NoteID, (*PI)->getRanges()); + Diag.Report(NoteLoc, NoteID) << (*PI)->getString() + << (*PI)->getRanges(); } } } @@ -157,8 +137,8 @@ public: namespace { -class AnalysisConsumer : public ASTConsumer, - public RecursiveASTVisitor<AnalysisConsumer> { +class AnalysisConsumer : public AnalysisASTConsumer, + public DataRecursiveASTVisitor<AnalysisConsumer> { enum { AM_None = 0, AM_Syntax = 0x1, @@ -191,8 +171,8 @@ public: StoreManagerCreator CreateStoreMgr; ConstraintManagerCreator CreateConstraintMgr; - OwningPtr<CheckerManager> checkerMgr; - OwningPtr<AnalysisManager> Mgr; + std::unique_ptr<CheckerManager> checkerMgr; + std::unique_ptr<AnalysisManager> Mgr; /// Time the analyzes time of each translation unit. static llvm::Timer* TUTotalTimer; @@ -205,8 +185,8 @@ public: const std::string& outdir, AnalyzerOptionsRef opts, ArrayRef<std::string> plugins) - : RecVisitorMode(0), RecVisitorBR(0), - Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins) { + : RecVisitorMode(0), RecVisitorBR(nullptr), + Ctx(nullptr), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins) { DigestAnalyzerOptions(); if (Opts->PrintStats) { llvm::EnableStatistics(); @@ -220,21 +200,24 @@ public: } void DigestAnalyzerOptions() { - // Create the PathDiagnosticConsumer. - ClangDiagPathDiagConsumer *clangDiags = - new ClangDiagPathDiagConsumer(PP.getDiagnostics()); - PathConsumers.push_back(clangDiags); - - if (Opts->AnalysisDiagOpt == PD_TEXT) { - clangDiags->enablePaths(); - - } else if (!OutDir.empty()) { - switch (Opts->AnalysisDiagOpt) { - default: -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ - case PD_##NAME: CREATEFN(*Opts.getPtr(), PathConsumers, OutDir, PP);\ - break; + if (Opts->AnalysisDiagOpt != PD_NONE) { + // Create the PathDiagnosticConsumer. + ClangDiagPathDiagConsumer *clangDiags = + new ClangDiagPathDiagConsumer(PP.getDiagnostics()); + PathConsumers.push_back(clangDiags); + + if (Opts->AnalysisDiagOpt == PD_TEXT) { + clangDiags->enablePaths(); + + } else if (!OutDir.empty()) { + switch (Opts->AnalysisDiagOpt) { + default: +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ + case PD_##NAME: \ + CREATEFN(*Opts.get(), PathConsumers, OutDir, PP); \ + break; #include "clang/StaticAnalyzer/Core/Analyses.def" + } } } @@ -299,7 +282,7 @@ public: } } - virtual void Initialize(ASTContext &Context) { + void Initialize(ASTContext &Context) override { Ctx = &Context; checkerMgr.reset(createCheckerManager(*Opts, PP.getLangOpts(), Plugins, PP.getDiagnostics())); @@ -315,16 +298,16 @@ public: /// \brief Store the top level decls in the set to be processed later on. /// (Doing this pre-processing avoids deserialization of data from PCH.) - virtual bool HandleTopLevelDecl(DeclGroupRef D); - virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D); + bool HandleTopLevelDecl(DeclGroupRef D) override; + void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override; - virtual void HandleTranslationUnit(ASTContext &C); + void HandleTranslationUnit(ASTContext &C) override; /// \brief Determine which inlining mode should be used when this function is /// analyzed. This allows to redefine the default inlining policies when /// analyzing a given function. ExprEngine::InliningModes - getInliningModeForFunction(const Decl *D, SetOfConstDecls Visited); + getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited); /// \brief Build the call graph for all the top level decls of this TU and /// use it to define the order in which the functions should be visited. @@ -338,7 +321,7 @@ public: /// given root function. void HandleCode(Decl *D, AnalysisMode Mode, ExprEngine::InliningModes IMode = ExprEngine::Inline_Minimal, - SetOfConstDecls *VisitedCallees = 0); + SetOfConstDecls *VisitedCallees = nullptr); void RunPathSensitiveChecks(Decl *D, ExprEngine::InliningModes IMode, @@ -389,6 +372,11 @@ public: return true; } + virtual void + AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) override { + PathConsumers.push_back(Consumer); + } + private: void storeTopLevelDecls(DeclGroupRef DG); @@ -402,7 +390,7 @@ private: //===----------------------------------------------------------------------===// // AnalysisConsumer implementation. //===----------------------------------------------------------------------===// -llvm::Timer* AnalysisConsumer::TUTotalTimer = 0; +llvm::Timer* AnalysisConsumer::TUTotalTimer = nullptr; bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) { storeTopLevelDecls(DG); @@ -426,8 +414,8 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) { } static bool shouldSkipFunction(const Decl *D, - SetOfConstDecls Visited, - SetOfConstDecls VisitedAsTopLevel) { + const SetOfConstDecls &Visited, + const SetOfConstDecls &VisitedAsTopLevel) { if (VisitedAsTopLevel.count(D)) return true; @@ -447,7 +435,7 @@ static bool shouldSkipFunction(const Decl *D, ExprEngine::InliningModes AnalysisConsumer::getInliningModeForFunction(const Decl *D, - SetOfConstDecls Visited) { + const SetOfConstDecls &Visited) { // We want to reanalyze all ObjC methods as top level to report Retain // Count naming convention errors more aggressively. But we should tune down // inlining when reanalyzing an already inlined function. @@ -501,7 +489,7 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { SetOfConstDecls VisitedCallees; HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited), - (Mgr->options.InliningMode == All ? 0 : &VisitedCallees)); + (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees)); // Add the visited callees to the global visited set. for (SetOfConstDecls::iterator I = VisitedCallees.begin(), @@ -551,14 +539,14 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { // After all decls handled, run checkers on the entire TranslationUnit. checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR); - RecVisitorBR = 0; + RecVisitorBR = nullptr; } // Explicitly destroy the PathDiagnosticConsumer. This will flush its output. // FIXME: This should be replaced with something that doesn't rely on // side-effects in PathDiagnosticConsumer's destructor. This is required when // used with option -disable-free. - Mgr.reset(NULL); + Mgr.reset(); if (TUTotalTimer) TUTotalTimer->stopTimer(); @@ -653,7 +641,7 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled, ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries,IMode); // Set the graph auditor. - OwningPtr<ExplodedNode::Auditor> Auditor; + std::unique_ptr<ExplodedNode::Auditor> Auditor; if (Mgr->options.visualizeExplodedGraphWithUbiGraph) { Auditor.reset(CreateUbiViz()); ExplodedNode::SetAuditor(Auditor.get()); @@ -665,7 +653,7 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled, // Release the auditor (if any) so that it doesn't monitor the graph // created BugReporter. - ExplodedNode::SetAuditor(0); + ExplodedNode::SetAuditor(nullptr); // Visualize the exploded graph. if (Mgr->options.visualizeExplodedGraphWithGraphViz) @@ -699,10 +687,10 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, // AnalysisConsumer creation. //===----------------------------------------------------------------------===// -ASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp, - const std::string& outDir, - AnalyzerOptionsRef opts, - ArrayRef<std::string> plugins) { +AnalysisASTConsumer * +ento::CreateAnalysisConsumer(const Preprocessor &pp, const std::string &outDir, + AnalyzerOptionsRef opts, + ArrayRef<std::string> plugins) { // Disable the effects of '-Werror' when using the AnalysisConsumer. pp.getDiagnostics().setWarningsAsErrors(false); @@ -716,7 +704,7 @@ ASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp, namespace { class UbigraphViz : public ExplodedNode::Auditor { - OwningPtr<raw_ostream> Out; + std::unique_ptr<raw_ostream> Out; std::string Filename; unsigned Cntr; @@ -724,11 +712,11 @@ class UbigraphViz : public ExplodedNode::Auditor { VMap M; public: - UbigraphViz(raw_ostream *Out, StringRef Filename); + UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename); ~UbigraphViz(); - virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst); + void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) override; }; } // end anonymous namespace @@ -739,10 +727,9 @@ static ExplodedNode::Auditor* CreateUbiViz() { llvm::sys::fs::createTemporaryFile("llvm_ubi", "", FD, P); llvm::errs() << "Writing '" << P.str() << "'.\n"; - OwningPtr<llvm::raw_fd_ostream> Stream; - Stream.reset(new llvm::raw_fd_ostream(FD, true)); + auto Stream = llvm::make_unique<llvm::raw_fd_ostream>(FD, true); - return new UbigraphViz(Stream.take(), P); + return new UbigraphViz(std::move(Stream), P); } void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { @@ -779,8 +766,8 @@ void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) { << ", ('arrow','true'), ('oriented', 'true'))\n"; } -UbigraphViz::UbigraphViz(raw_ostream *Out, StringRef Filename) - : Out(Out), Filename(Filename), Cntr(0) { +UbigraphViz::UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename) + : Out(std::move(Out)), Filename(Filename), Cntr(0) { *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n"; *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66')," @@ -788,16 +775,17 @@ UbigraphViz::UbigraphViz(raw_ostream *Out, StringRef Filename) } UbigraphViz::~UbigraphViz() { - Out.reset(0); + Out.reset(); llvm::errs() << "Running 'ubiviz' program... "; std::string ErrMsg; std::string Ubiviz = llvm::sys::FindProgramByName("ubiviz"); std::vector<const char*> args; args.push_back(Ubiviz.c_str()); args.push_back(Filename.c_str()); - args.push_back(0); + args.push_back(nullptr); - if (llvm::sys::ExecuteAndWait(Ubiviz, &args[0], 0, 0, 0, 0, &ErrMsg)) { + if (llvm::sys::ExecuteAndWait(Ubiviz, &args[0], nullptr, nullptr, 0, 0, + &ErrMsg)) { llvm::errs() << "Error viewing graph: " << ErrMsg << "\n"; } diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h deleted file mode 100644 index b75220b..0000000 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ /dev/null @@ -1,43 +0,0 @@ -//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header contains the functions necessary for a front-end to run various -// analyses. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H -#define LLVM_CLANG_GR_ANALYSISCONSUMER_H - -#include "clang/Basic/LLVM.h" -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" -#include <string> - -namespace clang { - -class ASTConsumer; -class Preprocessor; -class DiagnosticsEngine; - -namespace ento { -class CheckerManager; - -/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code -/// analysis passes. (The set of analyses run is controlled by command-line -/// options.) -ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp, - const std::string &output, - AnalyzerOptionsRef opts, - ArrayRef<std::string> plugins); - -} // end GR namespace - -} // end clang namespace - -#endif diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index e7def08..e2577c3 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -20,11 +20,11 @@ #include "clang/StaticAnalyzer/Core/CheckerOptInfo.h" #include "clang/StaticAnalyzer/Core/CheckerRegistry.h" #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include <memory> using namespace clang; using namespace ento; @@ -40,7 +40,7 @@ class ClangCheckerRegistry : public CheckerRegistry { public: ClangCheckerRegistry(ArrayRef<std::string> plugins, - DiagnosticsEngine *diags = 0); + DiagnosticsEngine *diags = nullptr); }; } // end anonymous namespace @@ -73,7 +73,7 @@ ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins, bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) { // If the version string is null, it's not an analyzer plugin. - if (versionString == 0) + if (!versionString) return false; // For now, none of the static analyzer API is considered stable. @@ -104,8 +104,8 @@ CheckerManager *ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, ArrayRef<std::string> plugins, DiagnosticsEngine &diags) { - OwningPtr<CheckerManager> checkerMgr(new CheckerManager(langOpts, - &opts)); + std::unique_ptr<CheckerManager> checkerMgr( + new CheckerManager(langOpts, &opts)); SmallVector<CheckerOptInfo, 8> checkerOpts; for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { @@ -123,7 +123,7 @@ CheckerManager *ento::createCheckerManager(AnalyzerOptions &opts, << checkerOpts[i].getName(); } - return checkerMgr.take(); + return checkerMgr.release(); } void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) { diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp index 13971af..aa38077 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Frontend/FrontendActions.cpp @@ -8,8 +8,8 @@ //===----------------------------------------------------------------------===// #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" -#include "AnalysisConsumer.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h" using namespace clang; using namespace ento; |