https://github.com/capitan-davide updated https://github.com/llvm/llvm-project/pull/162361
>From 5f61932af5a90b52b5939406a929734dd6353316 Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Fri, 24 Oct 2025 08:18:09 +0200 Subject: [PATCH 1/7] [clang-tidy] Add new check 'bugprone-inconsistent-ifelse-braces' --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../InconsistentIfelseBracesCheck.cpp | 95 +++++++++++++++ .../bugprone/InconsistentIfelseBracesCheck.h | 41 +++++++ clang-tools-extra/docs/ReleaseNotes.rst | 5 + .../bugprone/inconsistent-ifelse-braces.rst | 6 + .../docs/clang-tidy/checks/list.rst | 3 +- ...nconsistent-ifelse-braces-consteval-if.cpp | 28 +++++ .../bugprone/inconsistent-ifelse-braces.cpp | 108 ++++++++++++++++++ 9 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index fe261e729539c..e1e42d22c520e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -33,6 +33,7 @@ #include "ImplicitWideningOfMultiplicationResultCheck.h" #include "InaccurateEraseCheck.h" #include "IncDecInConditionsCheck.h" +#include "InconsistentIfelseBracesCheck.h" #include "IncorrectEnableIfCheck.h" #include "IncorrectEnableSharedFromThisCheck.h" #include "IncorrectRoundingsCheck.h" @@ -150,6 +151,8 @@ class BugproneModule : public ClangTidyModule { "bugprone-implicit-widening-of-multiplication-result"); CheckFactories.registerCheck<InaccurateEraseCheck>( "bugprone-inaccurate-erase"); + CheckFactories.registerCheck<InconsistentIfelseBracesCheck>( + "bugprone-inconsistent-ifelse-braces"); CheckFactories.registerCheck<IncorrectEnableIfCheck>( "bugprone-incorrect-enable-if"); CheckFactories.registerCheck<IncorrectEnableSharedFromThisCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 46bc8efd44bc5..d19fd5017d2e0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -28,6 +28,7 @@ add_clang_library(clangTidyBugproneModule STATIC ForwardingReferenceOverloadCheck.cpp ImplicitWideningOfMultiplicationResultCheck.cpp InaccurateEraseCheck.cpp + InconsistentIfelseBracesCheck.cpp IncorrectEnableIfCheck.cpp IncorrectEnableSharedFromThisCheck.cpp InvalidEnumDefaultInitializationCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp new file mode 100644 index 0000000000000..ab3da9f26b390 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp @@ -0,0 +1,95 @@ + +//===----------------------------------------------------------------------===// +// +// 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 "InconsistentIfelseBracesCheck.h" +#include "../utils/BracesAroundStatement.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +/// Check that at least one branch of the \p If statement is a \c CompoundStmt. +static bool shouldHaveBraces(const IfStmt *If) { + const Stmt *const Then = If->getThen(); + if (isa<CompoundStmt>(Then)) + return true; + + if (const Stmt *const Else = If->getElse()) { + if (const auto *NestedIf = dyn_cast<const IfStmt>(Else)) + return shouldHaveBraces(NestedIf); + + return isa<CompoundStmt>(Else); + } + + return false; +} + +void InconsistentIfelseBracesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + traverse(TK_IgnoreUnlessSpelledInSource, + ifStmt(hasElse(anything()), + unless(isConsteval()), // 'if consteval' always has braces + unless(hasParent(ifStmt()))) + .bind("if_stmt")), + this); +} + +void InconsistentIfelseBracesCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedIf = Result.Nodes.getNodeAs<IfStmt>("if_stmt"); + if (!shouldHaveBraces(MatchedIf)) + return; + + // TODO: Test behavior with macros. This might be the reason why + // readability-braces-around-statements defines a findRParenLoc() function + // rather than using IfStmt/WhileStmt::getRParenLoc(). + checkIfStmt(Result, MatchedIf); +} + +void InconsistentIfelseBracesCheck::checkIfStmt( + const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If) { + const Stmt *Then = If->getThen(); + if (const auto *NestedIf = dyn_cast<const IfStmt>(Then)) { + // If the then-branch is a nested IfStmt, first we need to add braces to + // it, then we need to check the inner IfStmt. + checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); + if (shouldHaveBraces(NestedIf)) + return checkIfStmt(Result, NestedIf); + } + + if (!isa<CompoundStmt>(Then)) + checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); + + if (const Stmt *const Else = If->getElse()) { + if (const auto *NestedIf = dyn_cast<const IfStmt>(Else)) + return checkIfStmt(Result, NestedIf); + + if (!isa<CompoundStmt>(Else)) + checkStmt(Result, If->getElse(), If->getElseLoc()); + } +} + +void InconsistentIfelseBracesCheck::checkStmt( + const ast_matchers::MatchFinder::MatchResult &Result, const Stmt *S, + SourceLocation StartLoc, SourceLocation EndLocHint) { + const SourceManager &SM = *Result.SourceManager; + const LangOptions &LangOpts = Result.Context->getLangOpts(); + + const utils::BraceInsertionHints Hints = + utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint); + if (Hints) { + DiagnosticBuilder Diag = diag(Hints.DiagnosticPos, "<message>"); + if (Hints.offersFixIts()) { + Diag << Hints.openingBraceFixIt() << Hints.closingBraceFixIt(); + } + } +} +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h new file mode 100644 index 0000000000000..b841579223be5 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h @@ -0,0 +1,41 @@ + +//===----------------------------------------------------------------------===// +// +// 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_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// FIXME: Write a short description. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.html +class InconsistentIfelseBracesCheck : public ClangTidyCheck { +public: + InconsistentIfelseBracesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } + +private: + void checkIfStmt(const ast_matchers::MatchFinder::MatchResult &Result, + const IfStmt *If); + void checkStmt(const ast_matchers::MatchFinder::MatchResult &Result, + const Stmt *S, SourceLocation StartLoc, + SourceLocation EndLocHint = SourceLocation()); +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 7cdff86beeec6..6ed9b93e8c226 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -157,6 +157,11 @@ Improvements to clang-tidy New checks ^^^^^^^^^^ +- New :doc:`bugprone-inconsistent-ifelse-braces + <clang-tidy/checks/bugprone/inconsistent-ifelse-braces>` check. + + FIXME: Write a short description. + - New :doc:`bugprone-invalid-enum-default-initialization <clang-tidy/checks/bugprone/invalid-enum-default-initialization>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst new file mode 100644 index 0000000000000..9592f39d6a13d --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst @@ -0,0 +1,6 @@ +.. title:: clang-tidy - bugprone-inconsistent-ifelse-braces + +bugprone-inconsistent-ifelse-braces +=================================== + +FIXME: Describe what patterns does the check detect and why. Give examples. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index c490d2ece2e0a..9438030c64828 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -101,6 +101,7 @@ Clang-Tidy Checks :doc:`bugprone-implicit-widening-of-multiplication-result <bugprone/implicit-widening-of-multiplication-result>`, "Yes" :doc:`bugprone-inaccurate-erase <bugprone/inaccurate-erase>`, "Yes" :doc:`bugprone-inc-dec-in-conditions <bugprone/inc-dec-in-conditions>`, + :doc:`bugprone-inconsistent-ifelse-braces <bugprone/inconsistent-ifelse-braces>`, :doc:`bugprone-incorrect-enable-if <bugprone/incorrect-enable-if>`, "Yes" :doc:`bugprone-incorrect-enable-shared-from-this <bugprone/incorrect-enable-shared-from-this>`, "Yes" :doc:`bugprone-incorrect-roundings <bugprone/incorrect-roundings>`, @@ -256,7 +257,7 @@ Clang-Tidy Checks :doc:`llvm-prefer-static-over-anonymous-namespace <llvm/prefer-static-over-anonymous-namespace>`, :doc:`llvm-twine-local <llvm/twine-local>`, "Yes" :doc:`llvm-use-new-mlir-op-builder <llvm/use-new-mlir-op-builder>`, "Yes" - :doc:`llvm-use-ranges <llvm/use-ranges>`, "Yes" + :doc:`llvm-use-ranges <llvm/use-ranges>`, :doc:`llvmlibc-callee-namespace <llvmlibc/callee-namespace>`, :doc:`llvmlibc-implementation-in-namespace <llvmlibc/implementation-in-namespace>`, :doc:`llvmlibc-inline-function-decl <llvmlibc/inline-function-decl>`, "Yes" diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp new file mode 100644 index 0000000000000..c950045dab69f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp @@ -0,0 +1,28 @@ +// RUN: %check_clang_tidy -std=c++23-or-later %s bugprone-inconsistent-ifelse-braces %t + +bool cond(const char *) { return false; } +void do_something(const char *) {} + +// Positive tests. +void f() { + if consteval { + if (cond("if1")) + do_something("if-consteval-single-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if1")) { + // CHECK-FIXES: } else { + } else { + if (cond("if1.1")) { + } else + do_something("if-consteval-single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { + // CHECK-FIXES: } + } +} + +// Negative tests. +void g() { +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp new file mode 100644 index 0000000000000..de5c79f3f8961 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp @@ -0,0 +1,108 @@ +// RUN: %check_clang_tidy %s bugprone-inconsistent-ifelse-braces %t + +bool cond(const char *) { return false; } +void do_something(const char *) {} + +// Positive tests. +void f() { + if (cond("if0") /*comment*/) do_something("if-same-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("if-same-line"); + // CHECK-FIXES: } else { + + if (cond("if0.1") /*comment*/) { + } else do_something("else-same-line"); + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { do_something("else-same-line"); + // CHECK-FIXES: } + + if (cond("if1")) + do_something("if-single-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if1")) { + // CHECK-FIXES: } else { + + if (cond("if1.1")) { + } else + do_something("else-single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { + // CHECK-FIXES: } + + if (cond("if2") /*comment*/) + // some comment + do_something("if-multi-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-5]]:31: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if2") /*comment*/) { + // CHECK-FIXES: } else { + + if (cond("if2.1") /*comment*/) { + } else + // some comment + do_something("else-multi-line"); + // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { + // CHECK-FIXES: } + + if (cond("if3")) do_something("elseif-same-line"); + else if (cond("if3")) { + } else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if3")) { do_something("elseif-same-line"); + // CHECK-FIXES: } else if (cond("if3")) { + + if (cond("if3.1")) { + } else if (cond("if3.1")) do_something("elseif-same-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-3]]:28: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else if (cond("if3.1")) { do_something("elseif-same-line"); + // CHECK-FIXES: } else { + + if (cond("if3.2")) { + } else if (cond("if3.2")) { + } else do_something("elseif-same-line"); + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { do_something("elseif-same-line"); + // CHECK-FIXES: } + + if (cond("if4-outer")) + if (cond("if4-inner")) + do_something("nested-if-single-line"); + else { + } + else { + } + // CHECK-MESSAGES: :[[@LINE-7]]:25: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:27: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if4-outer")) { + // CHECK-FIXES: if (cond("if4-inner")) { + // CHECK-FIXES: } else { + // CHECK-FIXES: } else { + + if (cond("if5")) + do_something("noelse-single-line"); + else if (cond("if5")) { + } + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if5")) { + // CHECK-FIXES: } else if (cond("if5")) { + + if (cond("if5.1")) { + } else if (cond("if5.1")) + do_something("noelse-single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else if (cond("if5.1")) { + // CHECK-FIXES: } +} + +// Negative tests. +void g() { +} >From 18e6ae847c45e851c886fb7ddbd820f578ede385 Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Sat, 25 Oct 2025 08:02:52 +0200 Subject: [PATCH 2/7] [clang-tidy] Add some tests to 'bugprone-inconsistent-ifelse-braces' --- ...nconsistent-ifelse-braces-consteval-if.cpp | 33 +++++++++++++++++-- .../bugprone/inconsistent-ifelse-braces.cpp | 27 +++++++++++---- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp index c950045dab69f..3eb51c39e2921 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp @@ -1,22 +1,33 @@ // RUN: %check_clang_tidy -std=c++23-or-later %s bugprone-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } + void do_something(const char *) {} // Positive tests. void f() { if consteval { if (cond("if1")) - do_something("if-consteval-single-line"); + do_something("if-single-line"); else { } // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [bugprone-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if1")) { // CHECK-FIXES: } else { + } + + if consteval { + if (cond("if2")) + do_something("if-single-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if (cond("if2")) { + // CHECK-FIXES: } else { } else { - if (cond("if1.1")) { + if (cond("if2.1")) { } else - do_something("if-consteval-single-line"); + do_something("else-single-line"); // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: <message> [bugprone-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } @@ -25,4 +36,20 @@ void f() { // Negative tests. void g() { + if consteval { + if (cond("if0")) { + do_something("if-single-line"); + } else if (cond("if0")) { + do_something("elseif-single-line"); + } else { + do_something("else-single-line"); + } + } else { + if (cond("if0.1")) + do_something("if-single-line"); + else if (cond("if0.1")) + do_something("elseif-single-line"); + else + do_something("else-single-line"); + } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp index de5c79f3f8961..42a06f475356c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp @@ -1,6 +1,7 @@ // RUN: %check_clang_tidy %s bugprone-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } + void do_something(const char *) {} // Positive tests. @@ -68,14 +69,14 @@ void f() { if (cond("if3.2")) { } else if (cond("if3.2")) { - } else do_something("elseif-same-line"); + } else do_something("else-same-line"); // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] - // CHECK-FIXES: } else { do_something("elseif-same-line"); + // CHECK-FIXES: } else { do_something("else-same-line"); // CHECK-FIXES: } if (cond("if4-outer")) if (cond("if4-inner")) - do_something("nested-if-single-line"); + do_something("if-single-line"); else { } else { @@ -88,7 +89,7 @@ void f() { // CHECK-FIXES: } else { if (cond("if5")) - do_something("noelse-single-line"); + do_something("if-single-line"); else if (cond("if5")) { } // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] @@ -97,7 +98,7 @@ void f() { if (cond("if5.1")) { } else if (cond("if5.1")) - do_something("noelse-single-line"); + do_something("elseif-single-line"); // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: <message> [bugprone-inconsistent-ifelse-braces] // CHECK-FIXES: } else if (cond("if5.1")) { // CHECK-FIXES: } @@ -105,4 +106,18 @@ void f() { // Negative tests. void g() { -} + if (cond("if0")) { + do_something("if-single-line"); + } else if (cond("if0")) { + do_something("elseif-single-line"); + } else { + do_something("else-single-line"); + } + + if (cond("if1")) + do_something("if-single-line"); + else if (cond("if1")) + do_something("elseif-single-line"); + else + do_something("else-single-line"); +} \ No newline at end of file >From 117eb015fc4deec01c63c7f10acfad5b811e346a Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Sat, 25 Oct 2025 08:40:34 +0200 Subject: [PATCH 3/7] [clang-tidy] Update documentation for 'bugprone-inconsistent-ifelse-braces' --- .../InconsistentIfelseBracesCheck.cpp | 18 +++------ .../bugprone/InconsistentIfelseBracesCheck.h | 4 +- clang-tools-extra/docs/ReleaseNotes.rst | 3 +- .../bugprone/inconsistent-ifelse-braces.rst | 38 ++++++++++++++++++- .../docs/clang-tidy/checks/list.rst | 2 +- .../bugprone/inconsistent-ifelse-braces.cpp | 2 +- 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp index ab3da9f26b390..0c6b3e3e3ff9c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -47,10 +46,6 @@ void InconsistentIfelseBracesCheck::check( const auto *MatchedIf = Result.Nodes.getNodeAs<IfStmt>("if_stmt"); if (!shouldHaveBraces(MatchedIf)) return; - - // TODO: Test behavior with macros. This might be the reason why - // readability-braces-around-statements defines a findRParenLoc() function - // rather than using IfStmt/WhileStmt::getRParenLoc(). checkIfStmt(Result, MatchedIf); } @@ -62,17 +57,15 @@ void InconsistentIfelseBracesCheck::checkIfStmt( // it, then we need to check the inner IfStmt. checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); if (shouldHaveBraces(NestedIf)) - return checkIfStmt(Result, NestedIf); - } - - if (!isa<CompoundStmt>(Then)) + checkIfStmt(Result, NestedIf); + } else if (!isa<CompoundStmt>(Then)) { checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); + } if (const Stmt *const Else = If->getElse()) { if (const auto *NestedIf = dyn_cast<const IfStmt>(Else)) - return checkIfStmt(Result, NestedIf); - - if (!isa<CompoundStmt>(Else)) + checkIfStmt(Result, NestedIf); + else if (!isa<CompoundStmt>(Else)) checkStmt(Result, If->getElse(), If->getElseLoc()); } } @@ -92,4 +85,5 @@ void InconsistentIfelseBracesCheck::checkStmt( } } } + } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h index b841579223be5..c818f46fea281 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -14,7 +13,8 @@ namespace clang::tidy::bugprone { -/// FIXME: Write a short description. +/// Detects `if`/`else` statements where one branch uses braces and the other +/// does not. /// /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.html diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6ed9b93e8c226..28bebceef1006 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -160,7 +160,8 @@ New checks - New :doc:`bugprone-inconsistent-ifelse-braces <clang-tidy/checks/bugprone/inconsistent-ifelse-braces>` check. - FIXME: Write a short description. + Detects ``if``/``else`` statements where one branch uses braces and the other + does not. - New :doc:`bugprone-invalid-enum-default-initialization <clang-tidy/checks/bugprone/invalid-enum-default-initialization>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst index 9592f39d6a13d..44f2d64452393 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst @@ -3,4 +3,40 @@ bugprone-inconsistent-ifelse-braces =================================== -FIXME: Describe what patterns does the check detect and why. Give examples. +Detects ``if``/``else`` statements where one branch uses braces and the other +does not. + +Before: + +.. code-block:: c++ + + if (condition) { + statement; + } else + statement; + + if (condition) + statement; + + if (condition) + statement; + else + statement; + +After: + +.. code-block:: c++ + + if (condition) { + statement; + } else { + statement; + } + + if (condition) + statement; + + if (condition) + statement; + else + statement; diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 9438030c64828..4c5b70f6c47e5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -101,7 +101,7 @@ Clang-Tidy Checks :doc:`bugprone-implicit-widening-of-multiplication-result <bugprone/implicit-widening-of-multiplication-result>`, "Yes" :doc:`bugprone-inaccurate-erase <bugprone/inaccurate-erase>`, "Yes" :doc:`bugprone-inc-dec-in-conditions <bugprone/inc-dec-in-conditions>`, - :doc:`bugprone-inconsistent-ifelse-braces <bugprone/inconsistent-ifelse-braces>`, + :doc:`bugprone-inconsistent-ifelse-braces <bugprone/inconsistent-ifelse-braces>`, "Yes" :doc:`bugprone-incorrect-enable-if <bugprone/incorrect-enable-if>`, "Yes" :doc:`bugprone-incorrect-enable-shared-from-this <bugprone/incorrect-enable-shared-from-this>`, "Yes" :doc:`bugprone-incorrect-roundings <bugprone/incorrect-roundings>`, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp index 42a06f475356c..3d4af258137ce 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp @@ -120,4 +120,4 @@ void g() { do_something("elseif-single-line"); else do_something("else-single-line"); -} \ No newline at end of file +} >From 40570f986a7bec192db25c1001294ca8f93d4c75 Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Mon, 27 Oct 2025 19:10:06 +0100 Subject: [PATCH 4/7] [clang-tidy] Apply suggestions from code review --- .../clang-tidy/bugprone/InconsistentIfelseBracesCheck.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h index c818f46fea281..cfdcfa6923124 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h @@ -24,9 +24,6 @@ class InconsistentIfelseBracesCheck : public ClangTidyCheck { : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { - return LangOpts.CPlusPlus; - } private: void checkIfStmt(const ast_matchers::MatchFinder::MatchResult &Result, >From 6a652cd535962254b7bcc3d5acaf0426aa8617bf Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Tue, 28 Oct 2025 13:11:23 +0100 Subject: [PATCH 5/7] [clang-tidy] Apply suggestions from code review Co-authored-by: Victor Chernyakin <[email protected]> --- .../clang-tidy/bugprone/InconsistentIfelseBracesCheck.h | 4 ++-- clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 +- .../checkers/bugprone/inconsistent-ifelse-braces.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h index cfdcfa6923124..a88fa66ffa499 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h @@ -17,7 +17,7 @@ namespace clang::tidy::bugprone { /// does not. /// /// For the user-facing documentation see: -/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.html +/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.html class InconsistentIfelseBracesCheck : public ClangTidyCheck { public: InconsistentIfelseBracesCheck(StringRef Name, ClangTidyContext *Context) @@ -30,7 +30,7 @@ class InconsistentIfelseBracesCheck : public ClangTidyCheck { const IfStmt *If); void checkStmt(const ast_matchers::MatchFinder::MatchResult &Result, const Stmt *S, SourceLocation StartLoc, - SourceLocation EndLocHint = SourceLocation()); + SourceLocation EndLocHint = {}); }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 4c5b70f6c47e5..99286f548cda1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -257,7 +257,7 @@ Clang-Tidy Checks :doc:`llvm-prefer-static-over-anonymous-namespace <llvm/prefer-static-over-anonymous-namespace>`, :doc:`llvm-twine-local <llvm/twine-local>`, "Yes" :doc:`llvm-use-new-mlir-op-builder <llvm/use-new-mlir-op-builder>`, "Yes" - :doc:`llvm-use-ranges <llvm/use-ranges>`, + :doc:`llvm-use-ranges <llvm/use-ranges>`, "Yes" :doc:`llvmlibc-callee-namespace <llvmlibc/callee-namespace>`, :doc:`llvmlibc-implementation-in-namespace <llvmlibc/implementation-in-namespace>`, :doc:`llvmlibc-inline-function-decl <llvmlibc/inline-function-decl>`, "Yes" diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp index 3d4af258137ce..dd76e7176e445 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s bugprone-inconsistent-ifelse-braces %t +// RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } >From 540a43cf30a77c0c30a0bb459c26e2796919087d Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Thu, 30 Oct 2025 20:35:43 +0100 Subject: [PATCH 6/7] [clang-tidy] Add some test for constexpr if --- ...nconsistent-ifelse-braces-consteval-if.cpp | 1 - ...nconsistent-ifelse-braces-constexpr-if.cpp | 122 ++++++++++++++++++ .../bugprone/inconsistent-ifelse-braces.cpp | 1 - 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp index 3eb51c39e2921..c42b353e9d242 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp @@ -1,7 +1,6 @@ // RUN: %check_clang_tidy -std=c++23-or-later %s bugprone-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } - void do_something(const char *) {} // Positive tests. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp new file mode 100644 index 0000000000000..f8a3d67fcfbd1 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp @@ -0,0 +1,122 @@ +// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-inconsistent-ifelse-braces %t + +constexpr bool cond(const char *) { return false; } +constexpr void do_something(const char *) {} + +// Positive tests. +void f() { + if constexpr (cond("if0") /*comment*/) do_something("if-same-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if0") /*comment*/) { do_something("if-same-line"); + // CHECK-FIXES: } else { + + if constexpr (cond("if0.1") /*comment*/) { + } else do_something("else-same-line"); + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { do_something("else-same-line"); + // CHECK-FIXES: } + + if constexpr (cond("if1")) + do_something("if-single-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if1")) { + // CHECK-FIXES: } else { + + if constexpr (cond("if1.1")) { + } else + do_something("else-single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { + // CHECK-FIXES: } + + if constexpr (cond("if2") /*comment*/) + // some comment + do_something("if-multi-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-5]]:41: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if2") /*comment*/) { + // CHECK-FIXES: } else { + + if constexpr (cond("if2.1") /*comment*/) { + } else + // some comment + do_something("else-multi-line"); + // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { + // CHECK-FIXES: } + + if constexpr (cond("if3")) do_something("elseif-same-line"); + else if constexpr (cond("if3")) { + } else { + } + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if3")) { do_something("elseif-same-line"); + // CHECK-FIXES: } else if constexpr (cond("if3")) { + + if constexpr (cond("if3.1")) { + } else if constexpr (cond("if3.1")) do_something("elseif-same-line"); + else { + } + // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else if constexpr (cond("if3.1")) { do_something("elseif-same-line"); + // CHECK-FIXES: } else { + + if constexpr (cond("if3.2")) { + } else if constexpr (cond("if3.2")) { + } else do_something("else-same-line"); + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else { do_something("else-same-line"); + // CHECK-FIXES: } + + if constexpr (cond("if4-outer")) + if constexpr (cond("if4-inner")) + do_something("if-single-line"); + else { + } + else { + } + // CHECK-MESSAGES: :[[@LINE-7]]:35: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:37: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if4-outer")) { + // CHECK-FIXES: if constexpr (cond("if4-inner")) { + // CHECK-FIXES: } else { + // CHECK-FIXES: } else { + + if constexpr (cond("if5")) + do_something("if-single-line"); + else if constexpr (cond("if5")) { + } + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: if constexpr (cond("if5")) { + // CHECK-FIXES: } else if constexpr (cond("if5")) { + + if constexpr (cond("if5.1")) { + } else if constexpr (cond("if5.1")) + do_something("elseif-single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-FIXES: } else if constexpr (cond("if5.1")) { + // CHECK-FIXES: } +} + +// Negative tests. +void g() { + if constexpr (cond("if0")) { + do_something("if-single-line"); + } else if constexpr (cond("if0")) { + do_something("elseif-single-line"); + } else { + do_something("else-single-line"); + } + + if constexpr (cond("if1")) + do_something("if-single-line"); + else if constexpr (cond("if1")) + do_something("elseif-single-line"); + else + do_something("else-single-line"); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp index dd76e7176e445..bcb97a1766a03 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp @@ -1,7 +1,6 @@ // RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } - void do_something(const char *) {} // Positive tests. >From 7e1efdd807514079c446d918d1526cb3fa5eaa8f Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Thu, 6 Nov 2025 19:52:20 +0100 Subject: [PATCH 7/7] [clang-tidy] Add some suggestions from code review Also, renamed from `bugprone-*` to `readability-*` --- .../bugprone/BugproneTidyModule.cpp | 3 - .../clang-tidy/bugprone/CMakeLists.txt | 1 - .../clang-tidy/readability/CMakeLists.txt | 1 + .../InconsistentIfelseBracesCheck.cpp | 40 +-- .../InconsistentIfelseBracesCheck.h | 23 +- .../readability/ReadabilityTidyModule.cpp | 3 + .../clang-tidy/validate_check.py | 277 ++++++++++++++++++ clang-tools-extra/docs/ReleaseNotes.rst | 4 +- .../docs/clang-tidy/checks/list.rst | 2 +- .../inconsistent-ifelse-braces.rst | 6 +- ...nconsistent-ifelse-braces-consteval-if.cpp | 8 +- ...nconsistent-ifelse-braces-constexpr-if.cpp | 28 +- .../inconsistent-ifelse-braces.cpp | 28 +- 13 files changed, 353 insertions(+), 71 deletions(-) rename clang-tools-extra/clang-tidy/{bugprone => readability}/InconsistentIfelseBracesCheck.cpp (66%) rename clang-tools-extra/clang-tidy/{bugprone => readability}/InconsistentIfelseBracesCheck.h (55%) create mode 100755 clang-tools-extra/clang-tidy/validate_check.py rename clang-tools-extra/docs/clang-tidy/checks/{bugprone => readability}/inconsistent-ifelse-braces.rst (76%) rename clang-tools-extra/test/clang-tidy/checkers/{bugprone => readability}/inconsistent-ifelse-braces-consteval-if.cpp (72%) rename clang-tools-extra/test/clang-tidy/checkers/{bugprone => readability}/inconsistent-ifelse-braces-constexpr-if.cpp (68%) rename clang-tools-extra/test/clang-tidy/checkers/{bugprone => readability}/inconsistent-ifelse-braces.cpp (65%) diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index e1e42d22c520e..fe261e729539c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -33,7 +33,6 @@ #include "ImplicitWideningOfMultiplicationResultCheck.h" #include "InaccurateEraseCheck.h" #include "IncDecInConditionsCheck.h" -#include "InconsistentIfelseBracesCheck.h" #include "IncorrectEnableIfCheck.h" #include "IncorrectEnableSharedFromThisCheck.h" #include "IncorrectRoundingsCheck.h" @@ -151,8 +150,6 @@ class BugproneModule : public ClangTidyModule { "bugprone-implicit-widening-of-multiplication-result"); CheckFactories.registerCheck<InaccurateEraseCheck>( "bugprone-inaccurate-erase"); - CheckFactories.registerCheck<InconsistentIfelseBracesCheck>( - "bugprone-inconsistent-ifelse-braces"); CheckFactories.registerCheck<IncorrectEnableIfCheck>( "bugprone-incorrect-enable-if"); CheckFactories.registerCheck<IncorrectEnableSharedFromThisCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index d19fd5017d2e0..46bc8efd44bc5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -28,7 +28,6 @@ add_clang_library(clangTidyBugproneModule STATIC ForwardingReferenceOverloadCheck.cpp ImplicitWideningOfMultiplicationResultCheck.cpp InaccurateEraseCheck.cpp - InconsistentIfelseBracesCheck.cpp IncorrectEnableIfCheck.cpp IncorrectEnableSharedFromThisCheck.cpp InvalidEnumDefaultInitializationCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 4b4c49d3b17d1..5b25c5e2dba13 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -24,6 +24,7 @@ add_clang_library(clangTidyReadabilityModule STATIC IdentifierLengthCheck.cpp IdentifierNamingCheck.cpp ImplicitBoolConversionCheck.cpp + InconsistentIfelseBracesCheck.cpp RedundantInlineSpecifierCheck.cpp InconsistentDeclarationParameterNameCheck.cpp IsolateDeclarationCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.cpp similarity index 66% rename from clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp rename to clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.cpp index 0c6b3e3e3ff9c..e2ceec4c6af5a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.cpp @@ -13,7 +13,7 @@ using namespace clang::ast_matchers; -namespace clang::tidy::bugprone { +namespace clang::tidy::readability { /// Check that at least one branch of the \p If statement is a \c CompoundStmt. static bool shouldHaveBraces(const IfStmt *If) { @@ -33,11 +33,10 @@ static bool shouldHaveBraces(const IfStmt *If) { void InconsistentIfelseBracesCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - traverse(TK_IgnoreUnlessSpelledInSource, - ifStmt(hasElse(anything()), - unless(isConsteval()), // 'if consteval' always has braces - unless(hasParent(ifStmt()))) - .bind("if_stmt")), + ifStmt(hasElse(anything()), + unless(isConsteval()), // 'if consteval' always has braces + unless(hasParent(ifStmt()))) + .bind("if_stmt"), this); } @@ -50,40 +49,41 @@ void InconsistentIfelseBracesCheck::check( } void InconsistentIfelseBracesCheck::checkIfStmt( - const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If) { + const MatchFinder::MatchResult &Result, const IfStmt *If) { const Stmt *Then = If->getThen(); if (const auto *NestedIf = dyn_cast<const IfStmt>(Then)) { // If the then-branch is a nested IfStmt, first we need to add braces to // it, then we need to check the inner IfStmt. - checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); + emitDiagnostic(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); if (shouldHaveBraces(NestedIf)) checkIfStmt(Result, NestedIf); } else if (!isa<CompoundStmt>(Then)) { - checkStmt(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); + emitDiagnostic(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc()); } if (const Stmt *const Else = If->getElse()) { if (const auto *NestedIf = dyn_cast<const IfStmt>(Else)) checkIfStmt(Result, NestedIf); else if (!isa<CompoundStmt>(Else)) - checkStmt(Result, If->getElse(), If->getElseLoc()); + emitDiagnostic(Result, If->getElse(), If->getElseLoc()); } } -void InconsistentIfelseBracesCheck::checkStmt( - const ast_matchers::MatchFinder::MatchResult &Result, const Stmt *S, +void InconsistentIfelseBracesCheck::emitDiagnostic( + const MatchFinder::MatchResult &Result, const Stmt *S, SourceLocation StartLoc, SourceLocation EndLocHint) { const SourceManager &SM = *Result.SourceManager; const LangOptions &LangOpts = Result.Context->getLangOpts(); - const utils::BraceInsertionHints Hints = - utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint); - if (Hints) { - DiagnosticBuilder Diag = diag(Hints.DiagnosticPos, "<message>"); - if (Hints.offersFixIts()) { - Diag << Hints.openingBraceFixIt() << Hints.closingBraceFixIt(); - } + if (!StartLoc.isMacroID()) { + const utils::BraceInsertionHints Hints = + utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint); + assert(Hints && Hints.offersFixIts() && "Expected hints or fix-its"); + diag(Hints.DiagnosticPos, "<message>") + << Hints.openingBraceFixIt() << Hints.closingBraceFixIt(); + } else { + diag(StartLoc, "<message-for-macro-expansions>") << StartLoc.isMacroID(); } } -} // namespace clang::tidy::bugprone +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.h similarity index 55% rename from clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h rename to clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.h index a88fa66ffa499..e75c68173acb4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h +++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfelseBracesCheck.h @@ -6,33 +6,38 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_INCONSISTENTIFELSEBRACESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_INCONSISTENTIFELSEBRACESCHECK_H #include "../ClangTidyCheck.h" +#include "clang/AST/ASTTypeTraits.h" +#include <optional> -namespace clang::tidy::bugprone { +namespace clang::tidy::readability { /// Detects `if`/`else` statements where one branch uses braces and the other /// does not. /// /// For the user-facing documentation see: -/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.html +/// https://clang.llvm.org/extra/clang-tidy/checks/readability/inconsistent-ifelse-braces.html class InconsistentIfelseBracesCheck : public ClangTidyCheck { public: InconsistentIfelseBracesCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } private: void checkIfStmt(const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If); - void checkStmt(const ast_matchers::MatchFinder::MatchResult &Result, - const Stmt *S, SourceLocation StartLoc, - SourceLocation EndLocHint = {}); + void emitDiagnostic(const ast_matchers::MatchFinder::MatchResult &Result, + const Stmt *S, SourceLocation StartLoc, + SourceLocation EndLocHint = {}); }; -} // namespace clang::tidy::bugprone +} // namespace clang::tidy::readability -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_INCONSISTENTIFELSEBRACESCHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 12f8cdb289dd2..16c5b881616c1 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -30,6 +30,7 @@ #include "IdentifierNamingCheck.h" #include "ImplicitBoolConversionCheck.h" #include "InconsistentDeclarationParameterNameCheck.h" +#include "InconsistentIfelseBracesCheck.h" #include "IsolateDeclarationCheck.h" #include "MagicNumbersCheck.h" #include "MakeMemberFunctionConstCheck.h" @@ -110,6 +111,8 @@ class ReadabilityModule : public ClangTidyModule { "readability-identifier-naming"); CheckFactories.registerCheck<ImplicitBoolConversionCheck>( "readability-implicit-bool-conversion"); + CheckFactories.registerCheck<InconsistentIfelseBracesCheck>( + "readability-inconsistent-ifelse-braces"); CheckFactories.registerCheck<MathMissingParenthesesCheck>( "readability-math-missing-parentheses"); CheckFactories.registerCheck<RedundantInlineSpecifierCheck>( diff --git a/clang-tools-extra/clang-tidy/validate_check.py b/clang-tools-extra/clang-tidy/validate_check.py new file mode 100755 index 0000000000000..b57f8192c8391 --- /dev/null +++ b/clang-tools-extra/clang-tidy/validate_check.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python3 +# +# ===-----------------------------------------------------------------------===# +# +# 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 +# +# ===-----------------------------------------------------------------------===# + +import argparse +import os +import re +import sys + +no_maximize = False + +# Adds a release notes entry. +def validate_file(single_file): + filename = os.path.normpath(single_file) + return validate_rst(filename) + +def validate_release_notes(clang_tidy_path): + filename = os.path.normpath(os.path.join(clang_tidy_path, + '../docs/ReleaseNotes.rst')) + validate_rst(filename) + +def validate_docs(module_path, module, check_name): + filename = os.path.normpath(os.path.join( + module_path, '../../docs/clang-tidy/checks/', + module, check_name + '.rst')) + validate_rst(filename) + +def validate_rst(filename): + with open(filename, 'r') as f: + lines = f.readlines() + + print(f'Checking {filename}...') + + line_num = 0 + ignore_last_line = False + in_code_block = False + skip_blank_line = False + previous_line_blank = False + last_non_empty_line = 0 + last_line = "" + for line in lines: + line_no_newline = line.rstrip('\r\n'); + line_num = line_num + 1 + current_line_length = len(line_no_newline) + + # Look for multiple blank lines. + if (previous_line_blank == True) and (current_line_length == 0): + print('warning: line %d multiple blank lines' % (line_num)) + previous_line_blank = False + + if current_line_length == 0: + previous_line_blank = True + ignore_last_line = True + continue + else: + previous_line_blank = False + last_non_empty_line=line_num + + # Look for trailing white space but not just a newline. + if current_line_length > 0 and len(line.rstrip()) != current_line_length: + print('warning: line %d trailing whitespace' % (line_num)) + + if skip_blank_line: + skip_blank_line = False + continue + + if (line.startswith(".. code-block::") or + line.startswith(".. code::") or + line.startswith(":orphan:") or + line.startswith("Examples:")): + in_code_block = True + skip_blank_line = True + ignore_last_line = True + continue + + if line.startswith(".. "): + in_code_block = False + ignore_last_line = True + continue + + # Look for places where the markup does match the text above. + if (not in_code_block and (line.startswith("---") or + line.startswith("===") or + line.startswith("^^^^"))): + if line_num > 1 and len(line) != len(last_line): + print('warning: line %d title and markup non matching lengths' + % (line_num)) + ignore_last_line = True + continue + + if (line.startswith(" :") or + line.startswith(" - ") or + line.startswith("``") or + line.startswith("===") or + line.startswith("---") or + line.startswith(" ") or + line.lstrip().startswith("* ") or + line.lstrip().startswith("- ") or + re.search(r"^\d+\. .*",line.lstrip())): + ignore_last_line = True + continue + + # URL can be longer than 80 characters just ignore those lines. + if (line.find("https:")!=-1 or + line.find("http:")!=-1 or + line.find(".html")!=-1): + ignore_last_line = True + continue + + # Look for double whitespaces often cause during editing. + # e.g.". The...." + if (current_line_length > 0 and line.lstrip().find(" ")!=-1): + if not in_code_block: + print('warning: line %d contains double spaces' % (line_num)) + + + # If we are in a code clock, and we've skipped the the first + # blank line and future blank line is the end of the code block. + if in_code_block: + if current_line_length == 0: + in_code_block = False + ignore_last_line = True + else: + continue + + # ignore very long clang check name + # <clang-tidy/checks/cert-dcl16-c>` to :doc:`readability-uppercase-literal-suffix + if line.lstrip().startswith("<clang-tidy"): + ignore_last_line = True + continue + + # Look to see if we cannot concatinate this line with the last one + # to make the previous line upto or closer to 80 characters. + if current_line_length > 80: + print('warning: line %d is in excess of 80 characters (%d) : %s...' + % (line_num, len(line), line)) + elif not can_lines_be_joined(current_line_length,last_line,line, + line_num,ignore_last_line): + ignore_last_line = False + + # Remember this line so we can check the previous line next time + last_line = line + + # After processing the whole file determine if we have and blank + # lines at the edit of the file + if line_num != last_non_empty_line: + print("warning: line %d %d empty lines at the end of the file\n" + % (last_non_empty_line,line_num-last_non_empty_line)) + return 1 + + return 0 + +# Look to see if we cannot concatinate this line with the last one +# to make the previous line upto or closer to 80 characters. +def can_lines_be_joined(current_line_length,last_line,line, + line_num,ignore_last_line): + if not no_maximize: + return False + if line_num <= 1: + return False + + length_last_line = len(last_line) + + if (length_last_line == 0 and length_last_line >= 80): + return False + + if ignore_last_line: + return False + + if current_line_length == 0: + return False + + # The previous line is smaller than 80 see if we can't + # add the first work from the next line. + words = line.split() + + # If there are no words to split we are done + if (len(words) ==0 or len(words[0]) == 0): + return False; + + # ignore joining what looks like quoted code or tag + if (words[0].startswith("`") or words[0].startswith("<")): + return False; + + # Allow for the space that would be needed and if its + # still less than 80 then ask user to concatinate + new_line_length = len(words[0]) + len(last_line) + + if new_line_length < 80: + print("warning: line %d maximize 80 characters by joining:" + "'[%s]' and '[%s...]\n" + % (line_num-1, last_line.rstrip(), words[0])) + return True + + return False + +def validate_all_checks(clang_tidy_path): + docs_dir = os.path.join(clang_tidy_path, '../docs/clang-tidy/checks') + filename = os.path.normpath(os.path.join(docs_dir, 'list.rst')) + + with open(filename, 'r') as f: + lines = f.readlines() + + doc_files = list(filter(lambda s: s.endswith('.rst') and s != 'list.rst', + os.listdir(docs_dir))) + doc_files.sort() + + for doc_file in doc_files: + filename = os.path.join(docs_dir, doc_file) + validate_rst(filename) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--check-all', + action='store_true', + help='check all the check rst files') + parser.add_argument( + '--no-maximize', + action='store_true', + help='do not check for maximizing the line to 80 characters') + parser.add_argument( + '--rst', + nargs = '?', + help='the rst file to be checked') + parser.add_argument( + 'module', + nargs = '?', + help='module directory under which to tidy check is found (e.g., misc)') + parser.add_argument( + 'check', + nargs= '?', + help='name of tidy check to check (e.g. foo-do-the-stuff)') + args = parser.parse_args() + + clang_tidy_path = os.path.dirname(sys.argv[0]) + no_maximize = args.no_maximize + + if args.check_all: + validate_release_notes(clang_tidy_path) + validate_all_checks(clang_tidy_path) + return 0 + + if args.rst: + return validate_file(args.rst) + + if not args.module or not args.check: + print('Both module and check must be specified.', file=sys.stderr) + parser.print_usage() + return 1 + + module = args.module + check_name = args.check + + if check_name.startswith(module): + print(f'Check name "{check_name}" must not start with the module "{module}". Exiting.', file=sys.stderr) + return 1 + + check_name_camel = ''.join(map(lambda elem: elem.capitalize(), + check_name.split('-'))) + 'Check' + module_path = os.path.join(clang_tidy_path, module) + + validate_release_notes(clang_tidy_path) + validate_docs(module_path, module, check_name) + print('You are ready to review!') + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 28bebceef1006..4ebb0838426ff 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -157,8 +157,8 @@ Improvements to clang-tidy New checks ^^^^^^^^^^ -- New :doc:`bugprone-inconsistent-ifelse-braces - <clang-tidy/checks/bugprone/inconsistent-ifelse-braces>` check. +- New :doc:`readability-inconsistent-ifelse-braces + <clang-tidy/checks/readability/inconsistent-ifelse-braces>` check. Detects ``if``/``else`` statements where one branch uses braces and the other does not. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 99286f548cda1..f485eb71923d3 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -101,7 +101,6 @@ Clang-Tidy Checks :doc:`bugprone-implicit-widening-of-multiplication-result <bugprone/implicit-widening-of-multiplication-result>`, "Yes" :doc:`bugprone-inaccurate-erase <bugprone/inaccurate-erase>`, "Yes" :doc:`bugprone-inc-dec-in-conditions <bugprone/inc-dec-in-conditions>`, - :doc:`bugprone-inconsistent-ifelse-braces <bugprone/inconsistent-ifelse-braces>`, "Yes" :doc:`bugprone-incorrect-enable-if <bugprone/incorrect-enable-if>`, "Yes" :doc:`bugprone-incorrect-enable-shared-from-this <bugprone/incorrect-enable-shared-from-this>`, "Yes" :doc:`bugprone-incorrect-roundings <bugprone/incorrect-roundings>`, @@ -387,6 +386,7 @@ Clang-Tidy Checks :doc:`readability-identifier-naming <readability/identifier-naming>`, "Yes" :doc:`readability-implicit-bool-conversion <readability/implicit-bool-conversion>`, "Yes" :doc:`readability-inconsistent-declaration-parameter-name <readability/inconsistent-declaration-parameter-name>`, "Yes" + :doc:`readability-inconsistent-ifelse-braces <readability/inconsistent-ifelse-braces>`, :doc:`readability-isolate-declaration <readability/isolate-declaration>`, "Yes" :doc:`readability-magic-numbers <readability/magic-numbers>`, :doc:`readability-make-member-function-const <readability/make-member-function-const>`, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst similarity index 76% rename from clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst rename to clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst index 44f2d64452393..4b236f8684b3b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/inconsistent-ifelse-braces.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst @@ -1,7 +1,7 @@ -.. title:: clang-tidy - bugprone-inconsistent-ifelse-braces +.. title:: clang-tidy - readability-inconsistent-ifelse-braces -bugprone-inconsistent-ifelse-braces -=================================== +readability-inconsistent-ifelse-braces +====================================== Detects ``if``/``else`` statements where one branch uses braces and the other does not. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp similarity index 72% rename from clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp rename to clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp index c42b353e9d242..47dcc1fc12992 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-consteval-if.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy -std=c++23-or-later %s bugprone-inconsistent-ifelse-braces %t +// RUN: %check_clang_tidy -std=c++23-or-later %s readability-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } void do_something(const char *) {} @@ -10,7 +10,7 @@ void f() { do_something("if-single-line"); else { } - // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if1")) { // CHECK-FIXES: } else { } @@ -20,14 +20,14 @@ void f() { do_something("if-single-line"); else { } - // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if2")) { // CHECK-FIXES: } else { } else { if (cond("if2.1")) { } else do_something("else-single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp similarity index 68% rename from clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp rename to clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp index f8a3d67fcfbd1..9601bd2a9a6b7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces-constexpr-if.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-inconsistent-ifelse-braces %t +// RUN: %check_clang_tidy -std=c++17-or-later %s readability-inconsistent-ifelse-braces %t constexpr bool cond(const char *) { return false; } constexpr void do_something(const char *) {} @@ -8,13 +8,13 @@ void f() { if constexpr (cond("if0") /*comment*/) do_something("if-same-line"); else { } - // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if0") /*comment*/) { do_something("if-same-line"); // CHECK-FIXES: } else { if constexpr (cond("if0.1") /*comment*/) { } else do_something("else-same-line"); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { do_something("else-same-line"); // CHECK-FIXES: } @@ -22,14 +22,14 @@ void f() { do_something("if-single-line"); else { } - // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if1")) { // CHECK-FIXES: } else { if constexpr (cond("if1.1")) { } else do_something("else-single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } @@ -38,7 +38,7 @@ void f() { do_something("if-multi-line"); else { } - // CHECK-MESSAGES: :[[@LINE-5]]:41: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-5]]:41: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if2") /*comment*/) { // CHECK-FIXES: } else { @@ -46,7 +46,7 @@ void f() { } else // some comment do_something("else-multi-line"); - // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } @@ -54,7 +54,7 @@ void f() { else if constexpr (cond("if3")) { } else { } - // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if3")) { do_something("elseif-same-line"); // CHECK-FIXES: } else if constexpr (cond("if3")) { @@ -62,14 +62,14 @@ void f() { } else if constexpr (cond("if3.1")) do_something("elseif-same-line"); else { } - // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else if constexpr (cond("if3.1")) { do_something("elseif-same-line"); // CHECK-FIXES: } else { if constexpr (cond("if3.2")) { } else if constexpr (cond("if3.2")) { } else do_something("else-same-line"); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { do_something("else-same-line"); // CHECK-FIXES: } @@ -80,8 +80,8 @@ void f() { } else { } - // CHECK-MESSAGES: :[[@LINE-7]]:35: warning: <message> [bugprone-inconsistent-ifelse-braces] - // CHECK-MESSAGES: :[[@LINE-7]]:37: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:35: warning: <message> [readability-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:37: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if4-outer")) { // CHECK-FIXES: if constexpr (cond("if4-inner")) { // CHECK-FIXES: } else { @@ -91,14 +91,14 @@ void f() { do_something("if-single-line"); else if constexpr (cond("if5")) { } - // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if constexpr (cond("if5")) { // CHECK-FIXES: } else if constexpr (cond("if5")) { if constexpr (cond("if5.1")) { } else if constexpr (cond("if5.1")) do_something("elseif-single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else if constexpr (cond("if5.1")) { // CHECK-FIXES: } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp similarity index 65% rename from clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp rename to clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp index bcb97a1766a03..e6c27ffec629f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/inconsistent-ifelse-braces.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-inconsistent-ifelse-braces %t +// RUN: %check_clang_tidy -std=c++98-or-later %s readability-inconsistent-ifelse-braces %t bool cond(const char *) { return false; } void do_something(const char *) {} @@ -8,13 +8,13 @@ void f() { if (cond("if0") /*comment*/) do_something("if-same-line"); else { } - // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("if-same-line"); // CHECK-FIXES: } else { if (cond("if0.1") /*comment*/) { } else do_something("else-same-line"); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { do_something("else-same-line"); // CHECK-FIXES: } @@ -22,14 +22,14 @@ void f() { do_something("if-single-line"); else { } - // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if1")) { // CHECK-FIXES: } else { if (cond("if1.1")) { } else do_something("else-single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } @@ -38,7 +38,7 @@ void f() { do_something("if-multi-line"); else { } - // CHECK-MESSAGES: :[[@LINE-5]]:31: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-5]]:31: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if2") /*comment*/) { // CHECK-FIXES: } else { @@ -46,7 +46,7 @@ void f() { } else // some comment do_something("else-multi-line"); - // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { // CHECK-FIXES: } @@ -54,7 +54,7 @@ void f() { else if (cond("if3")) { } else { } - // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if3")) { do_something("elseif-same-line"); // CHECK-FIXES: } else if (cond("if3")) { @@ -62,14 +62,14 @@ void f() { } else if (cond("if3.1")) do_something("elseif-same-line"); else { } - // CHECK-MESSAGES: :[[@LINE-3]]:28: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-3]]:28: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else if (cond("if3.1")) { do_something("elseif-same-line"); // CHECK-FIXES: } else { if (cond("if3.2")) { } else if (cond("if3.2")) { } else do_something("else-same-line"); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else { do_something("else-same-line"); // CHECK-FIXES: } @@ -80,8 +80,8 @@ void f() { } else { } - // CHECK-MESSAGES: :[[@LINE-7]]:25: warning: <message> [bugprone-inconsistent-ifelse-braces] - // CHECK-MESSAGES: :[[@LINE-7]]:27: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:25: warning: <message> [readability-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-7]]:27: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if4-outer")) { // CHECK-FIXES: if (cond("if4-inner")) { // CHECK-FIXES: } else { @@ -91,14 +91,14 @@ void f() { do_something("if-single-line"); else if (cond("if5")) { } - // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: if (cond("if5")) { // CHECK-FIXES: } else if (cond("if5")) { if (cond("if5.1")) { } else if (cond("if5.1")) do_something("elseif-single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: <message> [bugprone-inconsistent-ifelse-braces] + // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: <message> [readability-inconsistent-ifelse-braces] // CHECK-FIXES: } else if (cond("if5.1")) { // CHECK-FIXES: } } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
