diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:49 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:49 +0000 |
commit | 2298981669bf3bd63335a4be179bc0f96823a8f4 (patch) | |
tree | 1cbe2eb27f030d2d70b80ee5ca3c86bee7326a9f /lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | |
parent | 9a83721404652cea39e9f02ae3e3b5c964602a5c (diff) |
Notes
Diffstat (limited to 'lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index d87937d9b63d..454b61fd51a1 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -1,9 +1,8 @@ //===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -84,10 +83,11 @@ void ento::createTextPathDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts, namespace { class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer { DiagnosticsEngine &Diag; - bool IncludePath; + bool IncludePath, ShouldEmitAsError; + public: ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) - : Diag(Diag), IncludePath(false) {} + : Diag(Diag), IncludePath(false), ShouldEmitAsError(false) {} ~ClangDiagPathDiagConsumer() override {} StringRef getName() const override { return "ClangDiags"; } @@ -102,9 +102,14 @@ public: IncludePath = true; } + void enableWerror() { ShouldEmitAsError = true; } + void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags, FilesMade *filesMade) override { - unsigned WarnID = Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0"); + unsigned WarnID = + ShouldEmitAsError + ? Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0") + : Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0"); unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0"); for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(), @@ -191,7 +196,9 @@ public: /// Time the analyzes time of each translation unit. std::unique_ptr<llvm::TimerGroup> AnalyzerTimers; - std::unique_ptr<llvm::Timer> TUTotalTimer; + std::unique_ptr<llvm::Timer> SyntaxCheckTimer; + std::unique_ptr<llvm::Timer> ExprEngineTimer; + std::unique_ptr<llvm::Timer> BugReporterTimer; /// The information about analyzed functions shared throughout the /// translation unit. @@ -207,8 +214,13 @@ public: if (Opts->PrintStats || Opts->ShouldSerializeStats) { AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>( "analyzer", "Analyzer timers"); - TUTotalTimer = llvm::make_unique<llvm::Timer>( - "time", "Analyzer total time", *AnalyzerTimers); + SyntaxCheckTimer = llvm::make_unique<llvm::Timer>( + "syntaxchecks", "Syntax-based analysis time", *AnalyzerTimers); + ExprEngineTimer = llvm::make_unique<llvm::Timer>( + "exprengine", "Path exploration time", *AnalyzerTimers); + BugReporterTimer = llvm::make_unique<llvm::Timer>( + "bugreporter", "Path-sensitive report post-processing time", + *AnalyzerTimers); llvm::EnableStatistics(/* PrintOnExit= */ false); } } @@ -226,6 +238,9 @@ public: new ClangDiagPathDiagConsumer(PP.getDiagnostics()); PathConsumers.push_back(clangDiags); + if (Opts->AnalyzerWerror) + clangDiags->enableWerror(); + if (Opts->AnalysisDiagOpt == PD_TEXT) { clangDiags->enablePaths(); @@ -338,8 +353,42 @@ public: /// Handle callbacks for arbitrary Decls. bool VisitDecl(Decl *D) { AnalysisMode Mode = getModeForDecl(D, RecVisitorMode); - if (Mode & AM_Syntax) + if (Mode & AM_Syntax) { + if (SyntaxCheckTimer) + SyntaxCheckTimer->startTimer(); checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR); + if (SyntaxCheckTimer) + SyntaxCheckTimer->stopTimer(); + } + return true; + } + + bool VisitVarDecl(VarDecl *VD) { + if (!Opts->IsNaiveCTUEnabled) + return true; + + if (VD->hasExternalStorage() || VD->isStaticDataMember()) { + if (!cross_tu::containsConst(VD, *Ctx)) + return true; + } else { + // Cannot be initialized in another TU. + return true; + } + + if (VD->getAnyInitializer()) + return true; + + llvm::Expected<const VarDecl *> CTUDeclOrError = + CTU.getCrossTUDefinition(VD, Opts->CTUDir, Opts->CTUIndexName, + Opts->DisplayCTUProgress); + + if (!CTUDeclOrError) { + handleAllErrors(CTUDeclOrError.takeError(), + [&](const cross_tu::IndexError &IE) { + CTU.emitCrossTUDiagnostics(IE); + }); + } + return true; } @@ -529,7 +578,11 @@ static bool isBisonFile(ASTContext &C) { void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) { BugReporter BR(*Mgr); TranslationUnitDecl *TU = C.getTranslationUnitDecl(); + if (SyntaxCheckTimer) + SyntaxCheckTimer->startTimer(); checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR); + if (SyntaxCheckTimer) + SyntaxCheckTimer->stopTimer(); // Run the AST-only checks using the order in which functions are defined. // If inlining is not turned on, use the simplest function order for path @@ -571,8 +624,6 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) return; - if (TUTotalTimer) TUTotalTimer->startTimer(); - if (isBisonFile(C)) { reportAnalyzerProgress("Skipping bison-generated file\n"); } else if (Opts->DisableAllChecks) { @@ -585,8 +636,6 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { runAnalysisOnTranslationUnit(C); } - if (TUTotalTimer) TUTotalTimer->stopTimer(); - // Count how many basic blocks we have not covered. NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks(); NumVisitedBlocksInAnalyzedFunctions = @@ -710,8 +759,13 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode, BugReporter BR(*Mgr); - if (Mode & AM_Syntax) + if (Mode & AM_Syntax) { + if (SyntaxCheckTimer) + SyntaxCheckTimer->startTimer(); checkerMgr->runCheckersOnASTBody(D, *Mgr, BR); + if (SyntaxCheckTimer) + SyntaxCheckTimer->stopTimer(); + } if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) { RunPathSensitiveChecks(D, IMode, VisitedCallees); if (IMode != ExprEngine::Inline_Minimal) @@ -738,8 +792,12 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode); // Execute the worklist algorithm. + if (ExprEngineTimer) + ExprEngineTimer->startTimer(); Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D), Mgr->options.MaxNodesPerTopLevelFunction); + if (ExprEngineTimer) + ExprEngineTimer->stopTimer(); if (!Mgr->options.DumpExplodedGraphTo.empty()) Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo); @@ -749,7 +807,11 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, Eng.ViewGraph(Mgr->options.TrimGraph); // Display warnings. + if (BugReporterTimer) + BugReporterTimer->startTimer(); Eng.getBugReporter().FlushReports(); + if (BugReporterTimer) + BugReporterTimer->stopTimer(); } //===----------------------------------------------------------------------===// |