[clang-tools-extra] Add new check: do not return 0; at the end of main() in C++ (PR #77586)

Bhuminjay Soni via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 10 03:26:16 PST 2024


https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/77586

>From bae95013cd7f937a5496cafcd40a77cc563addb0 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Wed, 10 Jan 2024 16:48:43 +0530
Subject: [PATCH 1/2] Added check for redundant return statement

Signed-off-by: 11happy <soni5happy at gmail.com>
---
 .../clang-tidy/readability/CMakeLists.txt     |  1 +
 .../readability/DonotreturnzerocheckCheck.cpp | 54 +++++++++++++++++++
 .../readability/DonotreturnzerocheckCheck.h   | 30 +++++++++++
 .../readability/ReadabilityTidyModule.cpp     |  3 ++
 clang-tools-extra/docs/ReleaseNotes.rst       |  8 +++
 .../docs/clang-tidy/checks/list.rst           |  1 +
 .../readability/DoNotReturnZeroCheck.rst      | 25 +++++++++
 .../readability/DoNotReturnZeroCheck.cpp      |  8 +++
 8 files changed, 130 insertions(+)
 create mode 100644 clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.h
 create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/DoNotReturnZeroCheck.rst
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/DoNotReturnZeroCheck.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 408c822b861c5f..cb7741d6f56ce7 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -14,6 +14,7 @@ add_clang_library(clangTidyReadabilityModule
   ContainerSizeEmptyCheck.cpp
   ConvertMemberFunctionsToStatic.cpp
   DeleteNullPointerCheck.cpp
+  DonotreturnzerocheckCheck.cpp
   DuplicateIncludeCheck.cpp
   ElseAfterReturnCheck.cpp
   FunctionCognitiveComplexityCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
new file mode 100644
index 00000000000000..66ea29be3c54a8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
@@ -0,0 +1,54 @@
+//===--- DonotreturnzerocheckCheck.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 "DonotreturnzerocheckCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+
+
+namespace clang::tidy::readability {
+  bool isCPlusPlusOrC99(const LangOptions &LangOpts) {
+  return LangOpts.CPlusPlus || LangOpts.C99;
+  }
+
+void DonotreturnzerocheckCheck::registerMatchers(MatchFinder *Finder) {
+  // FIXME: Add matchers.
+  Finder->addMatcher(functionDecl(
+    isMain(),returns(asString("int"))
+  ).bind("main"), this);
+}
+
+void DonotreturnzerocheckCheck::check(const MatchFinder::MatchResult &Result) {
+  // FIXME: Add callback implementation.
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("main");
+  if(isCPlusPlusOrC99(Result.Context->getLangOpts())){
+    SourceLocation ReturnLoc;
+    if (MatchedDecl->hasBody()) {
+      const CompoundStmt *Body = dyn_cast<CompoundStmt>(MatchedDecl->getBody());
+      if (Body && !Body->body_empty()) {
+        const Stmt *LastStmt = Body->body_back();
+        if (const auto *Return = dyn_cast<ReturnStmt>(LastStmt)) {
+          ReturnLoc = Return->getReturnLoc();
+        }
+      }
+    }
+
+    if (ReturnLoc.isValid()) {
+      // Suggest removal of the redundant return statement.
+      diag(ReturnLoc, "redundant 'return 0;' at the end of main")
+          << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(ReturnLoc));
+    }
+
+  }
+
+}
+
+}
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.h b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.h
new file mode 100644
index 00000000000000..1407b8c1831c9d
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.h
@@ -0,0 +1,30 @@
+//===--- DonotreturnzerocheckCheck.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_READABILITY_DONOTRETURNZEROCHECKCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DONOTRETURNZEROCHECKCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// FIXME: Write a short description.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/DoNotReturnZeroCheck.html
+class DonotreturnzerocheckCheck : public ClangTidyCheck {
+public:
+  DonotreturnzerocheckCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_DONOTRETURNZEROCHECKCHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 0b0aad7c0dcb36..3c3bc4fa94b97c 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -19,6 +19,7 @@
 #include "ContainerSizeEmptyCheck.h"
 #include "ConvertMemberFunctionsToStatic.h"
 #include "DeleteNullPointerCheck.h"
+#include "DonotreturnzerocheckCheck.h"
 #include "DuplicateIncludeCheck.h"
 #include "ElseAfterReturnCheck.h"
 #include "FunctionCognitiveComplexityCheck.h"
@@ -62,6 +63,8 @@ namespace readability {
 class ReadabilityModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<DonotreturnzerocheckCheck>(
+        "readability-DoNotReturnZeroCheck");
     CheckFactories.registerCheck<AvoidConstParamsInDecls>(
         "readability-avoid-const-params-in-decls");
     CheckFactories.registerCheck<AvoidReturnWithVoidValueCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index b4d87e0ed2a67a..cb45a135842576 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -224,6 +224,14 @@ New checks
   Recommends the smallest possible underlying type for an ``enum`` or ``enum``
   class based on the range of its enumerators.
 
+- New :doc:`readability-DoNotReturnZeroCheck
+  <clang-tidy/checks/readability/DoNotReturnZeroCheck>` check.
+
+  The readability-DoNotReturnZeroCheck clang-tidy check identifies 
+  and suggests removal of redundant return 0; statements at the end of the main
+  function in C++ programs, enhancing code readability by eliminating unnecessary
+  code that is implicitly handled by modern C++ standards.
+
 - New :doc:`readability-reference-to-constructed-temporary
   <clang-tidy/checks/readability/reference-to-constructed-temporary>` check.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 2f86121ad87299..c0b1dfd05fcca0 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -336,6 +336,7 @@ Clang-Tidy Checks
    :doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
    :doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
    :doc:`portability-std-allocator-const <portability/std-allocator-const>`,
+   :doc:`readability-DoNotReturnZeroCheck <readability/DoNotReturnZeroCheck>`, "Yes"
    :doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
    :doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`,
    :doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/DoNotReturnZeroCheck.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/DoNotReturnZeroCheck.rst
new file mode 100644
index 00000000000000..3b6d0f86a3a1c6
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/DoNotReturnZeroCheck.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - readability-DoNotReturnZeroCheck
+
+readability-DoNotReturnZeroCheck
+================================
+
+This Check warns about redundant return statements returning zero.
+
+Before:
+
+.. code-block:: c++
+
+  int main(){
+    int a;
+    return 0;
+  }
+
+
+After:
+
+.. code-block:: c++
+
+  int main(){
+    int a;
+
+  }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/DoNotReturnZeroCheck.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/DoNotReturnZeroCheck.cpp
new file mode 100644
index 00000000000000..b2689e5eff907b
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/DoNotReturnZeroCheck.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy %s readability-DoNotReturnZeroCheck %t
+
+
+int main() {
+  return 0; // Should trigger a warning.
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant 'return 0;' at the end of main [readability-DoNotReturnZeroCheck]
+  // CHECK-FIXES: {{^}}int main() {{{$}}
+}
\ No newline at end of file

>From 9f65c865b2f66d0fee0e192670cbd59747a57a90 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Wed, 10 Jan 2024 16:55:44 +0530
Subject: [PATCH 2/2] Formatted the code

Signed-off-by: 11happy <soni5happy at gmail.com>
---
 .../readability/DonotreturnzerocheckCheck.cpp | 20 ++++++++-----------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
index 66ea29be3c54a8..4a741940bf55bf 100644
--- a/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/DonotreturnzerocheckCheck.cpp
@@ -12,24 +12,21 @@
 
 using namespace clang::ast_matchers;
 
-
-
 namespace clang::tidy::readability {
-  bool isCPlusPlusOrC99(const LangOptions &LangOpts) {
+bool isCPlusPlusOrC99(const LangOptions &LangOpts) {
   return LangOpts.CPlusPlus || LangOpts.C99;
-  }
+}
 
 void DonotreturnzerocheckCheck::registerMatchers(MatchFinder *Finder) {
   // FIXME: Add matchers.
-  Finder->addMatcher(functionDecl(
-    isMain(),returns(asString("int"))
-  ).bind("main"), this);
+  Finder->addMatcher(
+      functionDecl(isMain(), returns(asString("int"))).bind("main"), this);
 }
 
 void DonotreturnzerocheckCheck::check(const MatchFinder::MatchResult &Result) {
   // FIXME: Add callback implementation.
   const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>("main");
-  if(isCPlusPlusOrC99(Result.Context->getLangOpts())){
+  if (isCPlusPlusOrC99(Result.Context->getLangOpts())) {
     SourceLocation ReturnLoc;
     if (MatchedDecl->hasBody()) {
       const CompoundStmt *Body = dyn_cast<CompoundStmt>(MatchedDecl->getBody());
@@ -44,11 +41,10 @@ void DonotreturnzerocheckCheck::check(const MatchFinder::MatchResult &Result) {
     if (ReturnLoc.isValid()) {
       // Suggest removal of the redundant return statement.
       diag(ReturnLoc, "redundant 'return 0;' at the end of main")
-          << FixItHint::CreateRemoval(CharSourceRange::getTokenRange(ReturnLoc));
+          << FixItHint::CreateRemoval(
+                 CharSourceRange::getTokenRange(ReturnLoc));
     }
-
   }
-
 }
 
-}
\ No newline at end of file
+} // namespace clang::tidy::readability
\ No newline at end of file



More information about the cfe-commits mailing list