]> granicus.if.org Git - clang/commitdiff
Make DiagnosticErrorTrap keep a count of the errors that occurred so multiple
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 29 Jul 2011 01:25:44 +0000 (01:25 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 29 Jul 2011 01:25:44 +0000 (01:25 +0000)
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
lib/Basic/Diagnostic.cpp
lib/Basic/DiagnosticIDs.cpp
test/SemaCXX/scope-check.cpp

index b7a1f3a627d254f0d99e9f5501a79d1a627cb156..8cc1771f4f024065339b03c11d39207ffe512f47 100644 (file)
@@ -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;
   }
 };
 
index 38dadce98913286ba198aee40c1a8e5580f7e6a3..b82b062a729ead4c8acbaa1112a6df40664e1706 100644 (file)
@@ -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
index fbeec272d343041bc15cdce205e26bff6341515b..35b9605e1625f3d19486c5a950ff6d0913a14f03 100644 (file)
@@ -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;
index 3a90cc08f6a20d0ae42a48d28e04978fd34d2772..d656a074db3f1770675e095a1114b198012e94fa 100644 (file)
@@ -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;
+  }
+}
+}