[cfe-commits] r114093 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaStmt.cpp test/Sema/statements.c

Chris Lattner sabre at nondot.org
Thu Sep 16 10:09:42 PDT 2010


Author: lattner
Date: Thu Sep 16 12:09:42 2010
New Revision: 114093

URL: http://llvm.org/viewvc/llvm-project?rev=114093&view=rev
Log:
improve the "enumeration value 'g' not handled in switch"
warning to handle multiple enumerators with one warning.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/test/Sema/statements.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=114093&r1=114092&r2=114093&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 16 12:09:42 2010
@@ -3142,8 +3142,18 @@
 def warn_case_empty_range : Warning<"empty case range specified">;
 def warn_missing_case_for_condition :
   Warning<"no case matching constant switch condition '%0'">;
-def warn_missing_cases : Warning<"enumeration value %0 not handled in switch">,
+def warn_missing_case1 : Warning<"enumeration value %0 not handled in switch">,
   InGroup<DiagGroup<"switch-enum"> >;
+def warn_missing_case2 : Warning<
+  "enumeration values %0 and %1 not handled in switch">,
+  InGroup<DiagGroup<"switch-enum"> >;
+def warn_missing_case3 : Warning<
+  "enumeration values %0, %1, and %2 not handled in switch">,
+  InGroup<DiagGroup<"switch-enum"> >;
+def warn_missing_cases : Warning<
+  "%0 enumeration values not handled in switch: %1, %2, %3...">,
+  InGroup<DiagGroup<"switch-enum"> >;
+
 def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
   InGroup<DiagGroup<"switch-enum"> >; 
 def err_typecheck_statement_requires_scalar : Error<

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=114093&r1=114092&r2=114093&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Sep 16 12:09:42 2010
@@ -703,7 +703,7 @@
     // we still do the analysis to preserve this information in the AST
     // (which can be used by flow-based analyes).
     //
-    const EnumType* ET = CondTypeBeforePromotion->getAs<EnumType>();
+    const EnumType *ET = CondTypeBeforePromotion->getAs<EnumType>();
 
     // If switch has default case, then ignore it.
     if (!CaseListIsErroneous  && !HasConstantCond && ET) {
@@ -760,13 +760,16 @@
               << ED->getDeclName();
         }
       }
+      
       // Check which enum vals aren't in switch
       CaseValsTy::const_iterator CI = CaseVals.begin();
       CaseRangesTy::const_iterator RI = CaseRanges.begin();
       bool hasCasesNotInSwitch = false;
 
+      llvm::SmallVector<DeclarationName,8> UnhandledNames;
+      
       for (EnumValsTy::const_iterator EI = EnumVals.begin(); EI != EIend; EI++){
-        //Drop unneeded case values
+        // Drop unneeded case values
         llvm::APSInt CIVal;
         while (CI != CaseVals.end() && CI->first < EI->first)
           CI++;
@@ -784,10 +787,31 @@
         if (RI == CaseRanges.end() || EI->first < RI->first) {
           hasCasesNotInSwitch = true;
           if (!TheDefaultStmt)
-            Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
-              << EI->second->getDeclName();
+            UnhandledNames.push_back(EI->second->getDeclName());
         }
       }
+      
+      // Produce a nice diagnostic if multiple values aren't handled.
+      switch (UnhandledNames.size()) {
+      case 0: break;
+      case 1:
+        Diag(CondExpr->getExprLoc(), diag::warn_missing_case1)
+          << UnhandledNames[0];
+        break;
+      case 2:
+        Diag(CondExpr->getExprLoc(), diag::warn_missing_case2)
+          << UnhandledNames[0] << UnhandledNames[1];
+        break;
+      case 3:
+        Diag(CondExpr->getExprLoc(), diag::warn_missing_case3)
+          << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
+        break;
+      default:
+        Diag(CondExpr->getExprLoc(), diag::warn_missing_cases)
+          << (unsigned)UnhandledNames.size()
+          << UnhandledNames[0] << UnhandledNames[1] << UnhandledNames[2];
+        break;
+      }
 
       if (!hasCasesNotInSwitch)
         SS->setAllEnumCasesCovered();

Modified: cfe/trunk/test/Sema/statements.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/statements.c?rev=114093&r1=114092&r2=114093&view=diff
==============================================================================
--- cfe/trunk/test/Sema/statements.c (original)
+++ cfe/trunk/test/Sema/statements.c Thu Sep 16 12:09:42 2010
@@ -50,4 +50,43 @@
   case kThree:
     break;
   }
-}
\ No newline at end of file
+}
+
+
+enum x { a, b, c, d, e, f, g };
+
+void foo(enum x X) {
+  switch (X) { // expected-warning {{enumeration value 'g' not handled in switch}}
+  case a:
+  case b:
+  case c:
+  case d:
+  case e:
+  case f:
+    break;
+  }
+
+  switch (X) { // expected-warning {{enumeration values 'f' and 'g' not handled in switch}}
+  case a:
+  case b:
+  case c:
+  case d:
+  case e:
+    break;
+  }
+
+  switch (X) {  // expected-warning {{enumeration values 'e', 'f', and 'g' not handled in switch}}
+    case a:
+    case b:
+    case c:
+    case d:
+      break;
+  }
+
+  switch (X) { // expected-warning {{5 enumeration values not handled in switch: 'c', 'd', 'e'...}}
+  case a:
+  case b:
+    break;
+  }
+}
+





More information about the cfe-commits mailing list