Fix "warning: fallthrough annotation does not directly precede switch label" in lambdas.
authorAlexander Kornienko <alexfh@google.com>
Tue, 24 Jun 2014 15:28:21 +0000 (15:28 +0000)
committerAlexander Kornienko <alexfh@google.com>
Tue, 24 Jun 2014 15:28:21 +0000 (15:28 +0000)
Summary: This patch fixes http://llvm.org/PR17864 - "warning: fallthrough annotation does not directly precede switch label" in lambdas.

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: rnk, cfe-commits

Differential Revision: http://reviews.llvm.org/D4258

llvm-svn: 211599

clang/lib/Sema/AnalysisBasedWarnings.cpp
clang/test/SemaCXX/switch-implicit-fallthrough.cpp

index 0e522dc..c4524cd 100644 (file)
@@ -1025,6 +1025,9 @@ namespace {
     // methods separately.
     bool TraverseDecl(Decl *D) { return true; }
 
+    // We analyze lambda bodies separately. Skip them here.
+    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
+
   private:
 
     static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
index 831324a..0bc43cd 100644 (file)
@@ -229,25 +229,6 @@ int fallthrough_covered_enums(Enum e) {
   return n;
 }
 
-int fallthrough_targets(int n) {
-  [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
-
-  [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
-  switch (n) {
-    case 121:
-      n += 400;
-      [[clang::fallthrough]]; // no warning here, correct target
-    case 123:
-      [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
-      n += 800;
-      break;
-    [[clang::fallthrough]]    // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
-    case 125:
-      n += 1600;
-  }
-  return n;
-}
-
 // Fallthrough annotations in local classes used to generate "fallthrough
 // annotation does not directly precede switch label" warning.
 void fallthrough_in_local_class() {
@@ -259,12 +240,34 @@ void fallthrough_in_local_class() {
           [[clang::fallthrough]]; // no diagnostics
         case 1:
           x++;
+        default: // \
+            expected-warning{{unannotated fall-through between switch labels}} \
+            expected-note{{insert 'break;' to avoid fall-through}}
           break;
       }
     }
   };
 }
 
+// Fallthrough annotations in lambdas used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_lambda() {
+  (void)[] {
+    int x = 0;
+    switch (x) {
+    case 0:
+      x++;
+      [[clang::fallthrough]]; // no diagnostics
+    case 1:
+      x++;
+    default: // \
+        expected-warning{{unannotated fall-through between switch labels}} \
+        expected-note{{insert 'break;' to avoid fall-through}}
+      break;
+    }
+  };
+}
+
 namespace PR18983 {
   void fatal() __attribute__((noreturn));
   int num();
@@ -278,3 +281,22 @@ namespace PR18983 {
     }
   }
 }
+
+int fallthrough_targets(int n) {
+  [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
+
+  [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
+  switch (n) {
+    case 121:
+      n += 400;
+      [[clang::fallthrough]]; // no warning here, correct target
+    case 123:
+      [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
+      n += 800;
+      break;
+    [[clang::fallthrough]]    // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
+    case 125:
+      n += 1600;
+  }
+  return n;
+}