Once we've emitted a fatal diagnostic, keep counting errors but with a

separate count of "suppressed" errors. This way, semantic analysis
bits that depend on the error count to determine whether problems
occured (e.g., some template argument deduction failures, jump-scope
checking) will not get confused.

The actual problem here is that a missing #include (which is a fatal
error) could cause the jump-scope checker to run on invalid code,
which it is not prepared to do. Trivial fix for both
<rdar://problem/7775941> and <rdar://problem/7775709>.

llvm-svn: 101297
This commit is contained in:
Douglas Gregor 2010-04-14 22:19:45 +00:00
parent 99bfbca6ec
commit 2d2d90750c
4 changed files with 22 additions and 3 deletions

View File

@ -214,7 +214,8 @@ private:
unsigned NumWarnings; // Number of warnings reported unsigned NumWarnings; // Number of warnings reported
unsigned NumErrors; // Number of errors reported unsigned NumErrors; // Number of errors reported
unsigned NumErrorsSuppressed; // Number of errors suppressed
/// CustomDiagInfo - Information for uniquing and looking up custom diags. /// CustomDiagInfo - Information for uniquing and looking up custom diags.
diag::CustomDiagInfo *CustomDiagInfo; diag::CustomDiagInfo *CustomDiagInfo;
@ -343,6 +344,7 @@ public:
bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
unsigned getNumErrors() const { return NumErrors; } unsigned getNumErrors() const { return NumErrors; }
unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
unsigned getNumWarnings() const { return NumWarnings; } unsigned getNumWarnings() const { return NumWarnings; }
/// getCustomDiagID - Return an ID for a diagnostic with the specified message /// getCustomDiagID - Return an ID for a diagnostic with the specified message

View File

@ -227,6 +227,7 @@ Diagnostic::Diagnostic(DiagnosticClient *client) : Client(client) {
NumWarnings = 0; NumWarnings = 0;
NumErrors = 0; NumErrors = 0;
NumErrorsSuppressed = 0;
CustomDiagInfo = 0; CustomDiagInfo = 0;
CurDiagID = ~0U; CurDiagID = ~0U;
LastDiagLevel = Ignored; LastDiagLevel = Ignored;
@ -537,8 +538,14 @@ bool Diagnostic::ProcessDiag() {
// If a fatal error has already been emitted, silence all subsequent // If a fatal error has already been emitted, silence all subsequent
// diagnostics. // diagnostics.
if (FatalErrorOccurred) if (FatalErrorOccurred) {
if (DiagLevel >= Diagnostic::Error) {
++NumErrors;
++NumErrorsSuppressed;
}
return false; return false;
}
// If the client doesn't care about this message, don't issue it. If this is // If the client doesn't care about this message, don't issue it. If this is
// a note and the last real diagnostic was ignored, ignore it too. // a note and the last real diagnostic was ignored, ignore it too.

View File

@ -515,7 +515,8 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (getDiagnosticOpts().ShowCarets) { if (getDiagnosticOpts().ShowCarets) {
unsigned NumWarnings = getDiagnostics().getNumWarnings(); unsigned NumWarnings = getDiagnostics().getNumWarnings();
unsigned NumErrors = getDiagnostics().getNumErrors(); unsigned NumErrors = getDiagnostics().getNumErrors() -
getDiagnostics().getNumErrorsSuppressed();
if (NumWarnings) if (NumWarnings)
OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
#include "not exist" // expected-error{{'not exist' file not found}}
class AnalysisContext {};
static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {}
bool NoReturnEdge = false;
}