From c0a575f9b791a25c94b1c3c832dd73ec564646bb Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Fri, 29 Jul 2011 01:25:44 +0000 Subject: [PATCH] Make DiagnosticErrorTrap keep a count of the errors that occurred so multiple DiagnosticErrorTraps can be composed (e.g. a trap inside another trap). Fixes http://llvm.org/PR10462 & rdar://9852007. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136447 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Diagnostic.h | 16 +++++++++------- lib/Basic/Diagnostic.cpp | 2 ++ lib/Basic/DiagnosticIDs.cpp | 12 ++++++++---- test/SemaCXX/scope-check.cpp | 21 +++++++++++++++++++++ 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index b7a1f3a627..8cc1771f4f 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/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/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index 38dadce989..b82b062a72 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/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/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index fbeec272d3..35b9605e16 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/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/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp index 3a90cc08f6..d656a074db 100644 --- a/test/SemaCXX/scope-check.cpp +++ b/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; + } +} +} -- 2.40.0