[PATCH] D107933: [clang] Expose unreachable fallthrough annotation warning

Nathan Chancellor via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 11 15:23:58 PDT 2021


nathanchance created this revision.
nathanchance added reviewers: dblaikie, rsmith, nickdesaulniers.
nathanchance requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The Linux kernel has a macro called IS_ENABLED(), which evaluates to a
constant 1 or 0 based on Kconfig selections, allowing C code to be
unconditionally enabled or disabled at build time. For example:

int foo(struct *a, int b) {

  switch (b) {
  case 1:
      if (a->flag || !IS_ENABLED(CONFIG_64BIT))
          return 1;
      __attribute__((fallthrough));
  case 2:
      return 2;
  default:
      return 3;
  }

}

There is an unreachable warning about the fallthrough annotation in the
first case because !IS_ENABLED(CONFIG_64BIT) can be evaluated to 1,
which looks like

  return 1;
  __attribute__((fallthrough));

to clang.

This type of warning is pointless for the Linux kernel because it does
this trick all over the place due to the sheer number of configuration
options that it has.

Add -Wimplicit-fallthrough-unreachable, which is default enabled with
-Wimplicit-fallthrough to keep the status quo but allows projects to opt
out of the warning when they know these annotations may be unreachable
in certain conditions.

Fixes PR51094.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D107933

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/test/SemaCXX/switch-implicit-fallthrough.cpp


Index: clang/test/SemaCXX/switch-implicit-fallthrough.cpp
===================================================================
--- clang/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ clang/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -193,6 +193,28 @@
         ;
   }
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wimplicit-fallthrough-unreachable"
+  switch (n) {
+      n += 300;
+      [[clang::fallthrough]];  // no warning here
+    case 221:
+      return 1;
+      [[clang::fallthrough]];  // no warning here
+    case 222:
+      return 2;
+      __attribute__((fallthrough)); // no warning here
+    case 223:
+      if (1)
+        return 3;
+      __attribute__((fallthrough)); // no warning here
+    case 224:
+      n += 400;
+    case 225: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
+        ;
+  }
+#pragma clang diagnostic pop
+
   long p = static_cast<long>(n) * n;
   switch (sizeof(p)) {
     case 9:
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9580,7 +9580,7 @@
   "fallthrough annotation does not directly precede switch label">;
 def warn_fallthrough_attr_unreachable : Warning<
   "fallthrough annotation in unreachable code">,
-  InGroup<ImplicitFallthrough>, DefaultIgnore;
+  InGroup<ImplicitFallthroughUnreachable>, DefaultIgnore;
 
 def warn_unreachable_default : Warning<
   "default label in switch which covers all enumeration values">,
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -671,8 +671,11 @@
 def Switch         : DiagGroup<"switch">;
 def ImplicitFallthroughPerFunction :
   DiagGroup<"implicit-fallthrough-per-function">;
+def ImplicitFallthroughUnreachable :
+  DiagGroup<"implicit-fallthrough-unreachable">;
 def ImplicitFallthrough  : DiagGroup<"implicit-fallthrough",
-                                     [ImplicitFallthroughPerFunction]>;
+                                     [ImplicitFallthroughPerFunction,
+                                      ImplicitFallthroughUnreachable]>;
 def InvalidPPToken : DiagGroup<"invalid-pp-token">;
 def Trigraphs      : DiagGroup<"trigraphs">;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D107933.365861.patch
Type: text/x-patch
Size: 2585 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210811/62d745cf/attachment.bin>


More information about the cfe-commits mailing list