Do not perform the analysis based warning if the warnings are ignored

This saves some cycles when compiling with "-w".

(Also fix a potential crash on invalid code for tools that tries to recover from some
errors, because analysis might compute the CFG which crashes if the code contains
invalid declaration. This does not happen normally with because we also don't perform
these analysis if there was an error.)

Differential Revision: https://reviews.llvm.org/D40242

llvm-svn: 318900
This commit is contained in:
Olivier Goffart 2017-11-23 08:15:22 +00:00
parent 33894b619b
commit 270ced2bce
2 changed files with 30 additions and 4 deletions

View File

@ -2080,10 +2080,10 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
// time.
DiagnosticsEngine &Diags = S.getDiagnostics();
// Do not do any analysis for declarations in system headers if we are
// going to just ignore them.
if (Diags.getSuppressSystemWarnings() &&
S.SourceMgr.isInSystemHeader(D->getLocation()))
// Do not do any analysis if we are going to just ignore them.
if (Diags.getIgnoreAllWarnings() ||
(Diags.getSuppressSystemWarnings() &&
S.SourceMgr.isInSystemHeader(D->getLocation())))
return;
// For code in dependent contexts, we'll do this at instantiation time.

View File

@ -564,5 +564,31 @@ TEST(ClangToolTest, InjectDiagnosticConsumerInBuildASTs) {
}
#endif
TEST(runToolOnCode, TestResetDiagnostics) {
// This is a tool that resets the diagnostic during the compilation.
struct ResetDiagnosticAction : public clang::ASTFrontendAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
StringRef) override {
struct Consumer : public clang::ASTConsumer {
bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
auto &Diags = (*D.begin())->getASTContext().getDiagnostics();
// Ignore any error
Diags.Reset();
// Disable warnings because computing the CFG might crash.
Diags.setIgnoreAllWarnings(true);
return true;
}
};
return llvm::make_unique<Consumer>();
}
};
// Should not crash
EXPECT_FALSE(
runToolOnCode(new ResetDiagnosticAction,
"struct Foo { Foo(int); ~Foo(); struct Fwd _fwd; };"
"void func() { long x; Foo f(x); }"));
}
} // end namespace tooling
} // end namespace clang