summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Frontend
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-02-26 22:14:16 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-02-26 22:14:16 +0000
commit1d3e49e781a38bf9e2efd5ed9e001f92602e5552 (patch)
tree54e785e981a6ec941051d6651a16ddbb7e8c91a6 /clang/lib/StaticAnalyzer/Frontend
parent24f9794d78d54f659fd6760be6f8f0289e46ef3f (diff)
downloadbcm5719-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.cpp98
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();
OpenPOWER on IntegriCloud