diff options
-rw-r--r-- | clang/include/clang/Basic/Diagnostic.h | 16 | ||||
-rw-r--r-- | clang/lib/Basic/Diagnostic.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Basic/DiagnosticIDs.cpp | 12 | ||||
-rw-r--r-- | clang/test/SemaCXX/scope-check.cpp | 21 |
4 files changed, 40 insertions, 11 deletions
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index b7a1f3a627d..8cc1771f4f0 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -255,10 +255,10 @@ private: /// \brief Indicates that an unrecoverable error has occurred. bool UnrecoverableErrorOccurred; - /// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred + /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred /// during a parsing section, e.g. during parsing a function. - bool TrapErrorOccurred; - bool TrapUnrecoverableErrorOccurred; + unsigned TrapNumErrorsOccurred; + unsigned TrapNumUnrecoverableErrorsOccurred; /// LastDiagLevel - This is the level of the last diagnostic emitted. This is /// used to emit continuation diagnostics with the same level as the @@ -639,6 +639,8 @@ private: /// queried. class DiagnosticErrorTrap { Diagnostic &Diag; + unsigned NumErrors; + unsigned NumUnrecoverableErrors; public: explicit DiagnosticErrorTrap(Diagnostic &Diag) @@ -647,19 +649,19 @@ public: /// \brief Determine whether any errors have occurred since this /// object instance was created. bool hasErrorOccurred() const { - return Diag.TrapErrorOccurred; + return Diag.TrapNumErrorsOccurred > NumErrors; } /// \brief Determine whether any unrecoverable errors have occurred since this /// object instance was created. bool hasUnrecoverableErrorOccurred() const { - return Diag.TrapUnrecoverableErrorOccurred; + return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors; } // Set to initial state of "no errors occurred". void reset() { - Diag.TrapErrorOccurred = false; - Diag.TrapUnrecoverableErrorOccurred = false; + NumErrors = Diag.TrapNumErrorsOccurred; + NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred; } }; diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 38dadce9891..b82b062a729 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -92,6 +92,8 @@ void Diagnostic::Reset() { NumWarnings = 0; NumErrors = 0; NumErrorsSuppressed = 0; + TrapNumErrorsOccurred = 0; + TrapNumUnrecoverableErrorsOccurred = 0; CurDiagID = ~0U; // Set LastDiagLevel to an "unset" state. If we set it to 'Ignored', notes diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index fbeec272d34..35b9605e162 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -665,6 +665,13 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const { Diag.LastDiagLevel = DiagLevel; } + // Update counts for DiagnosticErrorTrap even if a fatal error occurred. + if (DiagLevel >= DiagnosticIDs::Error) { + ++Diag.TrapNumErrorsOccurred; + if (isUnrecoverable(DiagID)) + ++Diag.TrapNumUnrecoverableErrorsOccurred; + } + // If a fatal error has already been emitted, silence all subsequent // diagnostics. if (Diag.FatalErrorOccurred) { @@ -685,11 +692,8 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const { return false; if (DiagLevel >= DiagnosticIDs::Error) { - Diag.TrapErrorOccurred = true; - if (isUnrecoverable(DiagID)) { - Diag.TrapUnrecoverableErrorOccurred = true; + if (isUnrecoverable(DiagID)) Diag.UnrecoverableErrorOccurred = true; - } if (Diag.Client->IncludeInDiagnosticCounts()) { Diag.ErrorOccurred = true; diff --git a/clang/test/SemaCXX/scope-check.cpp b/clang/test/SemaCXX/scope-check.cpp index 3a90cc08f6a..d656a074db3 100644 --- a/clang/test/SemaCXX/scope-check.cpp +++ b/clang/test/SemaCXX/scope-check.cpp @@ -171,3 +171,24 @@ namespace test9 { } } } + +// http://llvm.org/PR10462 +namespace PR10462 { +enum MyEnum { + something_valid, + something_invalid +}; + +bool recurse() { + MyEnum K; + switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}} + case something_valid: + case what_am_i_thinking: // expected-error {{use of undeclared identifier}} + int *X = 0; + if (recurse()) { + } + + break; + } +} +} |