diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-02-26 22:14:16 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-02-26 22:14:16 +0000 |
commit | 1d3e49e781a38bf9e2efd5ed9e001f92602e5552 (patch) | |
tree | 54e785e981a6ec941051d6651a16ddbb7e8c91a6 /clang/lib/StaticAnalyzer/Frontend | |
parent | 24f9794d78d54f659fd6760be6f8f0289e46ef3f (diff) | |
download | bcm5719-llvm-1d3e49e781a38bf9e2efd5ed9e001f92602e5552.tar.gz bcm5719-llvm-1d3e49e781a38bf9e2efd5ed9e001f92602e5552.zip |
[analyzer] Do not analyze bison-generated files
Bison/YACC generated files result in a very large number of (presumably)
false positives from the analyzer.
These false positives are "true" in a sense of the information analyzer
sees: assuming that the lexer can return any token at any point a number
of uninitialized reads does occur.
(naturally, the analyzer can not capture a complex invariant that
certain tokens can only occur under certain conditions).
Current fix simply stops analysis on those files.
I have examined a very large number of such auto-generated files, and
they do all start with such a comment.
Conversely, user code is very unlikely to contain such a comment.
rdar://33608161
Differential Revision: https://reviews.llvm.org/D43421
llvm-svn: 326135
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend')
-rw-r--r-- | clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index a982a4a8566..a5cf61e90ec 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -389,7 +389,10 @@ private: /// \brief Check if we should skip (not analyze) the given function. AnalysisMode getModeForDecl(Decl *D, AnalysisMode Mode); + void runAnalysisOnTranslationUnit(ASTContext &C); + /// Print \p S to stderr if \c Opts->AnalyzerDisplayProgress is set. + void reportAnalyzerProgress(StringRef S); }; } // end anonymous namespace @@ -511,51 +514,72 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { } } +static bool isBisonFile(ASTContext &C) { + const SourceManager &SM = C.getSourceManager(); + FileID FID = SM.getMainFileID(); + StringRef Buffer = SM.getBuffer(FID)->getBuffer(); + if (Buffer.startswith("/* A Bison parser, made by")) + return true; + return false; +} + +void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) { + BugReporter BR(*Mgr); + TranslationUnitDecl *TU = C.getTranslationUnitDecl(); + checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR); + + // 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 + // sensitive analyzes as well. + RecVisitorMode = AM_Syntax; + if (!Mgr->shouldInlineCall()) + RecVisitorMode |= AM_Path; + RecVisitorBR = &BR; + + // Process all the top level declarations. + // + // Note: TraverseDecl may modify LocalTUDecls, but only by appending more + // entries. Thus we don't use an iterator, but rely on LocalTUDecls + // random access. By doing so, we automatically compensate for iterators + // possibly being invalidated, although this is a bit slower. + const unsigned LocalTUDeclsSize = LocalTUDecls.size(); + for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) { + TraverseDecl(LocalTUDecls[i]); + } + + if (Mgr->shouldInlineCall()) + HandleDeclsCallGraph(LocalTUDeclsSize); + + // After all decls handled, run checkers on the entire TranslationUnit. + checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR); + + RecVisitorBR = nullptr; +} + +void AnalysisConsumer::reportAnalyzerProgress(StringRef S) { + if (Opts->AnalyzerDisplayProgress) + llvm::errs() << S; +} + void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { + // Don't run the actions if an error has occurred with parsing the file. DiagnosticsEngine &Diags = PP.getDiagnostics(); if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred()) return; - // Don't analyze if the user explicitly asked for no checks to be performed - // on this file. - if (Opts->DisableAllChecks) - return; - - { - if (TUTotalTimer) TUTotalTimer->startTimer(); - - // Introduce a scope to destroy BR before Mgr. - BugReporter BR(*Mgr); - TranslationUnitDecl *TU = C.getTranslationUnitDecl(); - checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR); - - // 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 - // sensitive analyzes as well. - RecVisitorMode = AM_Syntax; - if (!Mgr->shouldInlineCall()) - RecVisitorMode |= AM_Path; - RecVisitorBR = &BR; - - // Process all the top level declarations. - // - // Note: TraverseDecl may modify LocalTUDecls, but only by appending more - // entries. Thus we don't use an iterator, but rely on LocalTUDecls - // random access. By doing so, we automatically compensate for iterators - // possibly being invalidated, although this is a bit slower. - const unsigned LocalTUDeclsSize = LocalTUDecls.size(); - for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) { - TraverseDecl(LocalTUDecls[i]); - } - - if (Mgr->shouldInlineCall()) - HandleDeclsCallGraph(LocalTUDeclsSize); + if (TUTotalTimer) TUTotalTimer->startTimer(); - // After all decls handled, run checkers on the entire TranslationUnit. - checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR); + if (isBisonFile(C)) { + reportAnalyzerProgress("Skipping bison-generated file\n"); + } else if (Opts->DisableAllChecks) { - RecVisitorBR = nullptr; + // Don't analyze if the user explicitly asked for no checks to be performed + // on this file. + reportAnalyzerProgress("All checks are disabled using a supplied option\n"); + } else { + // Otherwise, just run the analysis. + runAnalysisOnTranslationUnit(C); } if (TUTotalTimer) TUTotalTimer->stopTimer(); |