[clang-tools-extra] [clang-tidy] Add new check 'readability-inconsistent-ifelse-braces' (PR #162361)
Davide Cunial via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 24 02:30:33 PST 2025
https://github.com/capitan-davide updated https://github.com/llvm/llvm-project/pull/162361
>From 3c5ad1cdf7b97dee204733143282a8dac4a41b6d Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Fri, 24 Oct 2025 08:18:09 +0200
Subject: [PATCH 01/11] [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 e6115f67656bc..516c16bb9ae28 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -35,6 +35,7 @@
#include "ImplicitWideningOfMultiplicationResultCheck.h"
#include "InaccurateEraseCheck.h"
#include "IncDecInConditionsCheck.h"
+#include "InconsistentIfelseBracesCheck.h"
#include "IncorrectEnableIfCheck.h"
#include "IncorrectEnableSharedFromThisCheck.h"
#include "IncorrectRoundingsCheck.h"
@@ -157,6 +158,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 c8943e5b22ef8..5cedf6bcae510 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -30,6 +30,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 8f4be0d1cb259..c4b156b7de059 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -184,6 +184,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 d3c89e469188d..8e0e293c161db 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -103,6 +103,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 5fd485c2531e3f5e4fbaabcf03c1d103f218a5fc Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Sat, 25 Oct 2025 08:02:52 +0200
Subject: [PATCH 02/11] [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 ddb8f35138edda3d773d97c69a59e8f1b0ccf6df Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Sat, 25 Oct 2025 08:40:34 +0200
Subject: [PATCH 03/11] [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 c4b156b7de059..616d2f906037a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -187,7 +187,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 8e0e293c161db..bcd64b35e6367 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -103,7 +103,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 f8f551ba64289f6f046785824474148d97fb7ed5 Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Mon, 27 Oct 2025 19:10:06 +0100
Subject: [PATCH 04/11] [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 a683fa3e3e3853a68f67972f6f5c103235ced62a Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Tue, 28 Oct 2025 13:11:23 +0100
Subject: [PATCH 05/11] [clang-tidy] Apply suggestions from code review
Co-authored-by: Victor Chernyakin <chernyakin.victor.j at outlook.com>
---
.../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 bcd64b35e6367..01b0619f5b4f0 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 c77aad78f61cbf3405e8d8a2bc859e7713a7a958 Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Thu, 30 Oct 2025 20:35:43 +0100
Subject: [PATCH 06/11] [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 dfce0a026b78188db247c9ec74c6beb0de842e77 Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Thu, 6 Nov 2025 19:52:20 +0100
Subject: [PATCH 07/11] [clang-tidy] Add some suggestions from code review
Also, renamed from `bugprone-*` to `readability-*`
---
.../bugprone/BugproneTidyModule.cpp | 3 --
.../clang-tidy/bugprone/CMakeLists.txt | 1 -
.../bugprone/InconsistentIfelseBracesCheck.h | 38 ---------------
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../InconsistentIfElseBracesCheck.cpp} | 48 +++++++++----------
.../InconsistentIfElseBracesCheck.h | 43 +++++++++++++++++
.../readability/ReadabilityTidyModule.cpp | 3 ++
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, 109 insertions(+), 104 deletions(-)
delete mode 100644 clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h
rename clang-tools-extra/clang-tidy/{bugprone/InconsistentIfelseBracesCheck.cpp => readability/InconsistentIfElseBracesCheck.cpp} (60%)
create mode 100644 clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.h
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 516c16bb9ae28..e6115f67656bc 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -35,7 +35,6 @@
#include "ImplicitWideningOfMultiplicationResultCheck.h"
#include "InaccurateEraseCheck.h"
#include "IncDecInConditionsCheck.h"
-#include "InconsistentIfelseBracesCheck.h"
#include "IncorrectEnableIfCheck.h"
#include "IncorrectEnableSharedFromThisCheck.h"
#include "IncorrectRoundingsCheck.h"
@@ -158,8 +157,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 5cedf6bcae510..c8943e5b22ef8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -30,7 +30,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/bugprone/InconsistentIfelseBracesCheck.h b/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h
deleted file mode 100644
index a88fa66ffa499..0000000000000
--- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 {
-
-/// 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
-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;
-
-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 = {});
-};
-
-} // namespace clang::tidy::bugprone
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_INCONSISTENTIFELSEBRACESCHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 91e9354d454d2..6a5e90fc40b9d 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 60%
rename from clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp
rename to clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
index 0c6b3e3e3ff9c..07eceb79e4c95 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InconsistentIfelseBracesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
@@ -6,14 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#include "InconsistentIfelseBracesCheck.h"
+#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 {
+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) {
@@ -31,17 +31,16 @@ static bool shouldHaveBraces(const IfStmt *If) {
return false;
}
-void InconsistentIfelseBracesCheck::registerMatchers(MatchFinder *Finder) {
+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);
}
-void InconsistentIfelseBracesCheck::check(
+void InconsistentIfElseBracesCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *MatchedIf = Result.Nodes.getNodeAs<IfStmt>("if_stmt");
if (!shouldHaveBraces(MatchedIf))
@@ -49,41 +48,42 @@ void InconsistentIfelseBracesCheck::check(
checkIfStmt(Result, MatchedIf);
}
-void InconsistentIfelseBracesCheck::checkIfStmt(
- const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If) {
+void InconsistentIfElseBracesCheck::checkIfStmt(
+ 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/readability/InconsistentIfElseBracesCheck.h b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.h
new file mode 100644
index 0000000000000..d45b4743cdf39
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_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::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/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 emitDiagnostic(const ast_matchers::MatchFinder::MatchResult &Result,
+ const Stmt *S, SourceLocation StartLoc,
+ SourceLocation EndLocHint = {});
+};
+
+} // namespace clang::tidy::readability
+
+#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 569302e6065f2..d0fbc8286fdaa 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"
@@ -112,6 +113,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/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 616d2f906037a..15c5144850590 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -184,8 +184,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 01b0619f5b4f0..b9c9842088ff6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -103,7 +103,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>`,
@@ -389,6 +388,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>`, "Yes"
: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: }
}
>From eb72006dbd5a12666d834dea7c2ae4e91e56b538 Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Mon, 17 Nov 2025 20:42:11 +0100
Subject: [PATCH 08/11] [clang-tidy] Add some more tests
---
.../InconsistentIfElseBracesCheck.cpp | 10 +++--
.../inconsistent-ifelse-braces-attributes.cpp | 42 +++++++++++++++++++
.../inconsistent-ifelse-braces.cpp | 15 +++++++
3 files changed, 64 insertions(+), 3 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
index 07eceb79e4c95..01094e03d6efd 100644
--- a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
@@ -9,7 +9,10 @@
#include "InconsistentIfElseBracesCheck.h"
#include "../utils/BracesAroundStatement.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Stmt.h"
#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
using namespace clang::ast_matchers;
@@ -55,17 +58,19 @@ void InconsistentIfElseBracesCheck::checkIfStmt(
// If the then-branch is a nested IfStmt, first we need to add braces to
// it, then we need to check the inner IfStmt.
emitDiagnostic(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc());
+
if (shouldHaveBraces(NestedIf))
checkIfStmt(Result, NestedIf);
} else if (!isa<CompoundStmt>(Then)) {
- emitDiagnostic(Result, If->getThen(), If->getRParenLoc(), If->getElseLoc());
+ emitDiagnostic(Result, Then, 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))
+ else if (!isa<CompoundStmt>(Else)) {
emitDiagnostic(Result, If->getElse(), If->getElseLoc());
+ }
}
}
@@ -74,7 +79,6 @@ void InconsistentIfElseBracesCheck::emitDiagnostic(
SourceLocation StartLoc, SourceLocation EndLocHint) {
const SourceManager &SM = *Result.SourceManager;
const LangOptions &LangOpts = Result.Context->getLangOpts();
-
if (!StartLoc.isMacroID()) {
const utils::BraceInsertionHints Hints =
utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
new file mode 100644
index 0000000000000..738cafb37179f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy -std=c++20-or-later %s readability-inconsistent-ifelse-braces %t
+
+// Positive tests.
+void f(bool b) {
+ if (b) [[likely]] return;
+ else {
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { {{[[][[]}}likely{{[]][]]}} return;
+ // CHECK-FIXES: } else {
+
+ if (b) {
+ } else [[unlikely]]
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { {{[[][[]}}unlikely{{[]][]]}}
+}
+
+// Negative tests.
+void g(bool b) {
+ if (b) {
+ return;
+ }
+
+ if (b) { [[likely]]
+ return;
+ }
+
+ if (b) { [[unlikely]]
+ return;
+ } else { [[likely]]
+ return;
+ }
+
+ if (b) [[likely]]
+ return;
+
+ if (b) [[unlikely]]
+ return;
+ else [[likely]]
+ return;
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
index e6c27ffec629f..44668c98e036e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
@@ -1,5 +1,8 @@
// RUN: %check_clang_tidy -std=c++98-or-later %s readability-inconsistent-ifelse-braces %t
+#define MACRO_COND(x) cond(x)
+#define MACRO_FUN (void)0
+
bool cond(const char *) { return false; }
void do_something(const char *) {}
@@ -101,6 +104,18 @@ void f() {
// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: <message> [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else if (cond("if5.1")) {
// CHECK-FIXES: }
+
+ if (MACRO_COND("if6")) MACRO_FUN;
+ else {
+ }
+ // CHECK-MESSAGES: :[[@LINE-3]]:20: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (MACRO_COND("if6")) { MACRO_FUN;
+ // CHECK-FIXES: } else {
+
+ if (MACRO_COND("if6")) {
+ } else MACRO_FUN;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { MACRO_FUN;
}
// Negative tests.
>From de3acbfcc0b60cd0297f5575e5669d10cdddb4c9 Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Sun, 30 Nov 2025 16:56:50 +0100
Subject: [PATCH 09/11] [clang-tidy] Update diagnostic message
---
.../InconsistentIfElseBracesCheck.cpp | 2 +-
.../inconsistent-ifelse-braces-attributes.cpp | 4 +--
...nconsistent-ifelse-braces-consteval-if.cpp | 6 ++--
...nconsistent-ifelse-braces-constexpr-if.cpp | 26 ++++++++--------
.../inconsistent-ifelse-braces.cpp | 30 +++++++++----------
5 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
index 01094e03d6efd..904248f02e148 100644
--- a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
@@ -83,7 +83,7 @@ void InconsistentIfElseBracesCheck::emitDiagnostic(
const utils::BraceInsertionHints Hints =
utils::getBraceInsertionsHints(S, LangOpts, SM, StartLoc, EndLocHint);
assert(Hints && Hints.offersFixIts() && "Expected hints or fix-its");
- diag(Hints.DiagnosticPos, "<message>")
+ diag(Hints.DiagnosticPos, "statement should have braces")
<< Hints.openingBraceFixIt() << Hints.closingBraceFixIt();
} else {
diag(StartLoc, "<message-for-macro-expansions>") << StartLoc.isMacroID();
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
index 738cafb37179f..8fdb574227028 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-attributes.cpp
@@ -5,14 +5,14 @@ void f(bool b) {
if (b) [[likely]] return;
else {
}
- // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (b) { {{[[][[]}}likely{{[]][]]}} return;
// CHECK-FIXES: } else {
if (b) {
} else [[unlikely]]
return;
- // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else { {{[[][[]}}unlikely{{[]][]]}}
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp
index 47dcc1fc12992..2cfbb1bf363b1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-consteval-if.cpp
@@ -10,7 +10,7 @@ void f() {
do_something("if-single-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:21: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else {
// CHECK-FIXES: }
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp
index 9601bd2a9a6b7..3ad3afd8b8d61 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces-constexpr-if.cpp
@@ -8,13 +8,13 @@ void f() {
if constexpr (cond("if0") /*comment*/) do_something("if-same-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-5]]:41: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:38: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
- // CHECK-MESSAGES: :[[@LINE-7]]:37: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-7]]:35: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-7]]:37: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:29: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else if constexpr (cond("if5.1")) {
// CHECK-FIXES: }
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
index 44668c98e036e..3874719512f91 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-braces.cpp
@@ -11,13 +11,13 @@ void f() {
if (cond("if0") /*comment*/) do_something("if-same-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else { do_something("else-same-line");
// CHECK-FIXES: }
@@ -25,14 +25,14 @@ void f() {
do_something("if-single-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else {
// CHECK-FIXES: }
@@ -41,7 +41,7 @@ void f() {
do_something("if-multi-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-5]]:31: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-5]]:31: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (cond("if2") /*comment*/) {
// CHECK-FIXES: } else {
@@ -49,7 +49,7 @@ void f() {
} else
// some comment
do_something("else-multi-line");
- // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else {
// CHECK-FIXES: }
@@ -57,7 +57,7 @@ void f() {
else if (cond("if3")) {
} else {
}
- // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (cond("if3")) { do_something("elseif-same-line");
// CHECK-FIXES: } else if (cond("if3")) {
@@ -65,14 +65,14 @@ void f() {
} else if (cond("if3.1")) do_something("elseif-same-line");
else {
}
- // CHECK-MESSAGES: :[[@LINE-3]]:28: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:28: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else { do_something("else-same-line");
// CHECK-FIXES: }
@@ -83,8 +83,8 @@ void f() {
}
else {
}
- // CHECK-MESSAGES: :[[@LINE-7]]:25: warning: <message> [readability-inconsistent-ifelse-braces]
- // CHECK-MESSAGES: :[[@LINE-7]]:27: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-7]]:25: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-7]]:27: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (cond("if4-outer")) {
// CHECK-FIXES: if (cond("if4-inner")) {
// CHECK-FIXES: } else {
@@ -94,27 +94,27 @@ void f() {
do_something("if-single-line");
else if (cond("if5")) {
}
- // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-4]]:19: warning: statement should have braces [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> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else if (cond("if5.1")) {
// CHECK-FIXES: }
if (MACRO_COND("if6")) MACRO_FUN;
else {
}
- // CHECK-MESSAGES: :[[@LINE-3]]:20: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-3]]:25: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (MACRO_COND("if6")) { MACRO_FUN;
// CHECK-FIXES: } else {
if (MACRO_COND("if6")) {
} else MACRO_FUN;
- // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: <message> [readability-inconsistent-ifelse-braces]
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else { MACRO_FUN;
}
>From 4c9502634ec7369d8f13fa8b623a026fa24b069d Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Mon, 8 Dec 2025 14:59:47 +0100
Subject: [PATCH 10/11] [clang-tidy] Update diagnostic message
---
.../InconsistentIfElseBracesCheck.cpp | 22 +++++++++----------
clang-tools-extra/docs/ReleaseNotes.rst | 12 +++++-----
2 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
index 904248f02e148..e724dfb009146 100644
--- a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
@@ -68,26 +68,24 @@ void InconsistentIfElseBracesCheck::checkIfStmt(
if (const Stmt *const Else = If->getElse()) {
if (const auto *NestedIf = dyn_cast<const IfStmt>(Else))
checkIfStmt(Result, NestedIf);
- else if (!isa<CompoundStmt>(Else)) {
+ else if (!isa<CompoundStmt>(Else))
emitDiagnostic(Result, If->getElse(), If->getElseLoc());
- }
}
}
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();
- 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, "statement should have braces")
- << Hints.openingBraceFixIt() << Hints.closingBraceFixIt();
- } else {
- diag(StartLoc, "<message-for-macro-expansions>") << StartLoc.isMacroID();
+ if (StartLoc.isMacroID()) {
+ diag(StartLoc, "statement should have braces") << StartLoc.isMacroID();
+ return;
}
+ const utils::BraceInsertionHints Hints = utils::getBraceInsertionsHints(
+ S, Result.Context->getLangOpts(), *Result.SourceManager, StartLoc,
+ EndLocHint);
+ assert(Hints && Hints.offersFixIts() && "Expected hints or fix-its");
+ diag(Hints.DiagnosticPos, "statement should have braces")
+ << Hints.openingBraceFixIt() << Hints.closingBraceFixIt();
}
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 728a458f10104..b91036fc9664c 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -191,12 +191,6 @@ Improvements to clang-tidy
New checks
^^^^^^^^^^
-- 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.
-
- New :doc:`bugprone-derived-method-shadowing-base-method
<clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
@@ -239,6 +233,12 @@ New checks
Finds virtual function overrides with different visibility than the function
in the base class.
+- 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.
+
- New :doc:`readability-redundant-parentheses
<clang-tidy/checks/readability/redundant-parentheses>` check.
>From 523baaad750232383e52932858290176efaa9e8c Mon Sep 17 00:00:00 2001
From: Davide Cunial <dcunial at proton.me>
Date: Wed, 24 Dec 2025 10:45:50 +0100
Subject: [PATCH 11/11] [clang-tidy][NFC] Remove trailing whitespaces
---
.../checks/readability/inconsistent-ifelse-braces.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst
index 4b236f8684b3b..53a79808b2147 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/inconsistent-ifelse-braces.rst
@@ -17,7 +17,7 @@ Before:
if (condition)
statement;
-
+
if (condition)
statement;
else
@@ -35,7 +35,7 @@ After:
if (condition)
statement;
-
+
if (condition)
statement;
else
More information about the cfe-commits
mailing list