[cfe-commits] r157871 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/AnalysisBasedWarnings.cpp test/SemaCXX/switch-implicit-fallthrough-per-method.cpp

Alexander Kornienko alexfh at google.com
Fri Jun 1 18:01:08 PDT 2012


Author: alexfh
Date: Fri Jun  1 20:01:07 2012
New Revision: 157871

URL: http://llvm.org/viewvc/llvm-project?rev=157871&view=rev
Log:
Implementation of a "soft opt-in" option for -Wimplicit-fallthrough diagnostics: -Wimplicit-fallthrough-per-method

Added:
    cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=157871&r1=157870&r2=157871&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jun  1 20:01:07 2012
@@ -209,7 +209,9 @@
 def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
 def SwitchEnum     : DiagGroup<"switch-enum">;
 def Switch         : DiagGroup<"switch">;
-def ImplicitFallthrough  : DiagGroup<"implicit-fallthrough">;
+def ImplicitFallthroughPerMethod : DiagGroup<"implicit-fallthrough-per-method">;
+def ImplicitFallthrough  : DiagGroup<"implicit-fallthrough",
+                                     [ImplicitFallthroughPerMethod]>;
 def Trigraphs      : DiagGroup<"trigraphs">;
 
 def : DiagGroup<"type-limits">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157871&r1=157870&r2=157871&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jun  1 20:01:07 2012
@@ -5297,6 +5297,9 @@
 def warn_unannotated_fallthrough : Warning<
   "unannotated fall-through between switch labels">,
   InGroup<ImplicitFallthrough>, DefaultIgnore;
+def warn_unannotated_fallthrough_per_method : Warning<
+  "unannotated fall-through between switch labels in partly annotated method">,
+  InGroup<ImplicitFallthroughPerMethod>, DefaultIgnore;
 def note_insert_fallthrough_fixit : Note<
   "insert '[[clang::fallthrough]];' to silence this warning">;
 def note_insert_break_fixit : Note<

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=157871&r1=157870&r2=157871&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Fri Jun  1 20:01:07 2012
@@ -814,13 +814,17 @@
   };
 }
 
-static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC) {
+static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
+                                            bool PerMethod) {
   FallthroughMapper FM(S);
   FM.TraverseStmt(AC.getBody());
 
   if (!FM.foundSwitchStatements())
     return;
 
+  if (PerMethod && FM.getFallthroughStmts().empty())
+    return;
+
   CFG *Cfg = AC.getCFG();
 
   if (!Cfg)
@@ -838,7 +842,9 @@
     if (!FM.checkFallThroughIntoBlock(B, AnnotatedCnt))
       continue;
 
-    S.Diag(Label->getLocStart(), diag::warn_unannotated_fallthrough);
+    S.Diag(Label->getLocStart(),
+        PerMethod ? diag::warn_unannotated_fallthrough_per_method
+                  : diag::warn_unannotated_fallthrough);
 
     if (!AnnotatedCnt) {
       SourceLocation L = Label->getLocStart();
@@ -1324,9 +1330,14 @@
     }
   }
 
-  if (Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
-                              D->getLocStart()) != DiagnosticsEngine::Ignored) {
-    DiagnoseSwitchLabelsFallthrough(S, AC);
+  bool FallThroughDiagFull =
+      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
+                               D->getLocStart()) != DiagnosticsEngine::Ignored;
+  bool FallThroughDiagPerMethod =
+      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_method,
+                               D->getLocStart()) != DiagnosticsEngine::Ignored;
+  if (FallThroughDiagFull || FallThroughDiagPerMethod) {
+    DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
   }
 
   // Collect statistics about the CFG if it was built.

Added: cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp?rev=157871&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp (added)
+++ cfe/trunk/test/SemaCXX/switch-implicit-fallthrough-per-method.cpp Fri Jun  1 20:01:07 2012
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough-per-method %s
+
+
+int fallthrough(int n) {
+  switch (n / 10) {
+    case 0:
+      n += 100;
+    case 1:  // expected-warning{{unannotated fall-through between switch labels in partly annotated method}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+      switch (n) {
+      case 111:
+        n += 111;
+        [[clang::fallthrough]];
+      case 112:
+        n += 112;
+      case 113:  // expected-warning{{unannotated fall-through between switch labels in partly annotated method}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+        n += 113;
+        break    ;
+      }
+  }
+  return n;
+}
+
+int fallthrough2(int n) {
+  switch (n / 10) {
+    case 0:
+      n += 100;
+    case 1:  // no warning, as we didn't "opt-in" for it in this method
+      switch (n) {
+      case 111:
+        n += 111;
+      case 112:  // no warning, as we didn't "opt-in" for it in this method
+        n += 112;
+      case 113:  // no warning, as we didn't "opt-in" for it in this method
+        n += 113;
+        break    ;
+      }
+  }
+  return n;
+}





More information about the cfe-commits mailing list