[PATCH] D73852: [clang] detect switch fallthrough marked by a comment (PR43465)

Luboš Luňák via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 3 10:42:00 PST 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rG398b4ed87d48: [clang] detect switch fallthrough marked by a comment (PR43465) (authored by llunak).
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73852/new/

https://reviews.llvm.org/D73852

Files:
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/test/Sema/fallthrough-comment.c


Index: clang/test/Sema/fallthrough-comment.c
===================================================================
--- /dev/null
+++ clang/test/Sema/fallthrough-comment.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c11 -verify -Wimplicit-fallthrough %s
+
+int fallthrough_comment(int n) {
+  switch (n) {
+  case 0:
+    n++;
+    // FALLTHROUGH
+  case 1:
+    n++;
+
+    /*fall-through.*/
+
+  case 2:
+    n++;
+  case 3: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '__attribute__((fallthrough));' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+    n++;
+    break;
+  }
+  return n;
+}
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===================================================================
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1148,6 +1148,11 @@
           continue;
         }
 
+        if (isFollowedByFallThroughComment(LastStmt)) {
+          ++AnnotatedCnt;
+          continue; // Fallthrough comment, good.
+        }
+
         ++UnannotatedCnt;
       }
       return !!UnannotatedCnt;
@@ -1208,10 +1213,41 @@
       return nullptr;
     }
 
+    bool isFollowedByFallThroughComment(const Stmt *Statement) {
+      // Try to detect whether the fallthough is marked by a comment like
+      // /*FALLTHOUGH*/.
+      bool Invalid;
+      const char *SourceData = S.getSourceManager().getCharacterData(
+          Statement->getEndLoc(), &Invalid);
+      if (Invalid)
+        return false;
+      const char *LineStart = SourceData;
+      for (;;) {
+        LineStart = strchr(LineStart, '\n');
+        if (LineStart == nullptr)
+          return false;
+        ++LineStart; // Start of next line.
+        const char *LineEnd = strchr(LineStart, '\n');
+        StringRef Line(LineStart,
+                       LineEnd ? LineEnd - LineStart : strlen(LineStart));
+        if (LineStart == LineEnd ||
+            Line.find_first_not_of(" \t\r") == StringRef::npos)
+          continue; // Whitespace-only line.
+        if (!FallthroughRegex.isValid())
+          FallthroughRegex =
+              llvm::Regex("(/\\*[ \\t]*fall(s | |-)?thr(ough|u)\\.?[ \\t]*\\*/)"
+                          "|(//[ \\t]*fall(s | |-)?thr(ough|u)\\.?[ \\t]*)",
+                          llvm::Regex::IgnoreCase);
+        assert(FallthroughRegex.isValid());
+        return FallthroughRegex.match(Line);
+      }
+    }
+
     bool FoundSwitchStatements;
     AttrStmts FallthroughStmts;
     Sema &S;
     llvm::SmallPtrSet<const CFGBlock *, 16> ReachableBlocks;
+    llvm::Regex FallthroughRegex;
   };
 } // anonymous namespace
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73852.242125.patch
Type: text/x-patch
Size: 2699 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200203/a5839516/attachment-0001.bin>


More information about the cfe-commits mailing list