trixirt created this revision.
trixirt added reviewers: alexfh, nickdesaulniers.
trixirt added projects: clang, clang-tools-extra.
Herald added subscribers: cfe-commits, xazax.hun, mgorny.
trixirt requested review of this revision.
Cleaning up -Wextra-semi-stmt in the linux kernel shows a high
incidence of 'switch() {} ;' The ';' is not needed.
This is special case of the Parser::ConsumeExtraSemi() fixer.
This fixer allows the fixes to be batched and takes care of the
formatting issue of having an empty line when the ';' is removed.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D90180
Files:
clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.cpp
clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.h
clang-tools-extra/test/clang-tidy/checkers/linuxkernel-switch-semi.c
Index: clang-tools-extra/test/clang-tidy/checkers/linuxkernel-switch-semi.c
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/linuxkernel-switch-semi.c
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s linuxkernel-switch-semi %t
+
+int f(int a) {
+ switch (a) {
+ case 1:
+ return 0;
+ default:
+ break;
+ };
+ // CHECK-MESSAGES: warning: unneeded semicolon
+ // CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+ return 0;
+}
Index: clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.h
@@ -0,0 +1,30 @@
+//===--- SwitchSemiCheck.h - clang-tidy----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_SWITCHSEMICHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_SWITCHSEMICHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace linuxkernel {
+
+class SwitchSemiCheck : public ClangTidyCheck {
+public:
+ SwitchSemiCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace linuxkernel
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LINUXKERNEL_SWITCHSEMICHECK_H
Index: clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/linuxkernel/SwitchSemiCheck.cpp
@@ -0,0 +1,50 @@
+//===--- SwitchSemiCheck.cpp - clang-tidy----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SwitchSemiCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace linuxkernel {
+
+void SwitchSemiCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ compoundStmt(has(switchStmt().bind("switch"))).bind("comp"), this);
+}
+
+void SwitchSemiCheck::check(const MatchFinder::MatchResult &Result) {
+ auto *C = Result.Nodes.getNodeAs<CompoundStmt>("comp");
+ auto *S = Result.Nodes.getNodeAs<SwitchStmt>("switch");
+
+ auto Current = C->body_begin();
+ auto Next = Current;
+ Next++;
+ while (Next != C->body_end()) {
+ if (*Current == S) {
+ if (const auto *N = dyn_cast<NullStmt>(*Next)) {
+ if (!N->hasLeadingEmptyMacro() && S->getBody()->getEndLoc().isValid() &&
+ N->getSemiLoc().isValid()) {
+ auto H = FixItHint::CreateReplacement(
+ SourceRange(S->getBody()->getEndLoc(), N->getSemiLoc()), "}");
+ diag(N->getSemiLoc(), "unneeded semicolon") << H;
+ break;
+ }
+ }
+ }
+ Current = Next;
+ Next++;
+ }
+}
+
+} // namespace linuxkernel
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
+++ clang-tools-extra/clang-tidy/linuxkernel/LinuxKernelTidyModule.cpp
@@ -10,6 +10,7 @@
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "MustCheckErrsCheck.h"
+#include "SwitchSemiCheck.h"
namespace clang {
namespace tidy {
@@ -21,6 +22,8 @@
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<MustCheckErrsCheck>(
"linuxkernel-must-check-errs");
+ CheckFactories.registerCheck<SwitchSemiCheck>(
+ "linuxkernel-switch-semi");
}
};
// Register the LinuxKernelTidyModule using this statically initialized
Index: clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt
@@ -6,6 +6,7 @@
add_clang_library(clangTidyLinuxKernelModule
LinuxKernelTidyModule.cpp
MustCheckErrsCheck.cpp
+ SwitchSemiCheck.cpp
LINK_LIBS
clangTidy
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits