Author: Nathan Chancellor Date: 2021-08-16T17:14:55-07:00 New Revision: 9ed4a94d6451046a51ef393cd62f00710820a7e8
URL: https://github.com/llvm/llvm-project/commit/9ed4a94d6451046a51ef393cd62f00710820a7e8 DIFF: https://github.com/llvm/llvm-project/commit/9ed4a94d6451046a51ef393cd62f00710820a7e8.diff LOG: [clang] Expose unreachable fallthrough annotation warning 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 -Wunreachable-code-fallthrough, enabled under -Wunreachable-code, so that projects that want to warn on unreachable code get this warning but projects that do not care about unreachable code can still use -Wimplicit-fallthrough without having to make changes to their code base. Fixes PR51094. Reviewed By: aaron.ballman, nickdesaulniers Differential Revision: https://reviews.llvm.org/D107933 Added: Modified: clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/AnalysisBasedWarnings.cpp clang/test/SemaCXX/P30636.cpp clang/test/SemaCXX/switch-implicit-fallthrough.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 30dadd9731c15..17b5f419ef58c 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -821,8 +821,10 @@ def ReservedIdentifier : DiagGroup<"reserved-identifier", // under separate flags. // def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">; +def UnreachableCodeFallthrough : DiagGroup<"unreachable-code-fallthrough">; def UnreachableCode : DiagGroup<"unreachable-code", - [UnreachableCodeLoopIncrement]>; + [UnreachableCodeLoopIncrement, + UnreachableCodeFallthrough]>; def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">; def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">; def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive", diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9eaa696d99913..41152212c0d12 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -682,6 +682,9 @@ def warn_unreachable_return : Warning< def warn_unreachable_loop_increment : Warning< "loop will run at most once (loop increment never executed)">, InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore; +def warn_unreachable_fallthrough_attr : Warning< + "fallthrough annotation in unreachable code">, + InGroup<UnreachableCodeFallthrough>, DefaultIgnore; def note_unreachable_silence : Note< "silence by adding parentheses to mark code as explicitly dead">; @@ -9578,9 +9581,6 @@ def err_fallthrough_attr_outside_switch : Error< "fallthrough annotation is outside switch statement">; def err_fallthrough_attr_invalid_placement : Error< "fallthrough annotation does not directly precede switch label">; -def warn_fallthrough_attr_unreachable : Warning< - "fallthrough annotation in unreachable code">, - InGroup<ImplicitFallthrough>, DefaultIgnore; def warn_unreachable_default : Warning< "default label in switch which covers all enumeration values">, diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index aa2602c8d9256..99ce143d3559d 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1125,7 +1125,7 @@ namespace { // unreachable in all instantiations of the template. if (!IsTemplateInstantiation) S.Diag(AS->getBeginLoc(), - diag::warn_fallthrough_attr_unreachable); + diag::warn_unreachable_fallthrough_attr); markFallthroughVisited(AS); ++AnnotatedCnt; break; diff --git a/clang/test/SemaCXX/P30636.cpp b/clang/test/SemaCXX/P30636.cpp index 2e2affb0cfdea..1d5400d3ba0ed 100644 --- a/clang/test/SemaCXX/P30636.cpp +++ b/clang/test/SemaCXX/P30636.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -Wunreachable-code-fallthrough %s // expected-no-diagnostics template<bool param> diff --git a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp index 9676664a7a30a..0b790813506c3 100644 --- a/clang/test/SemaCXX/switch-implicit-fallthrough.cpp +++ b/clang/test/SemaCXX/switch-implicit-fallthrough.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough -Wunreachable-code-fallthrough %s int fallthrough(int n) { @@ -193,6 +193,26 @@ int fallthrough_position(int n) { ; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code-fallthrough" + 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; + } +#pragma clang diagnostic pop + long p = static_cast<long>(n) * n; switch (sizeof(p)) { case 9: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits