[clang-tools-extra] [clang-tidy] Ignore label-like statements when checking if/else bodies (PR #202869)
Gaurav Dhingra via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 11 02:21:54 PDT 2026
https://github.com/gxyd updated https://github.com/llvm/llvm-project/pull/202869
>From ec0096577ae49c08539af30c2ddb8c40e13969f5 Mon Sep 17 00:00:00 2001
From: Gaurav Dhingra <gauravdhingra.gxyd at gmail.com>
Date: Wed, 10 Jun 2026 12:23:40 +0530
Subject: [PATCH 1/2] [clang-tidy] Ignore label-like statements when checking
if/else bodies
Fixes #194694
---
.../InconsistentIfElseBracesCheck.cpp | 15 +--
clang-tools-extra/docs/ReleaseNotes.rst | 4 +
.../inconsistent-ifelse-labels.cpp | 126 ++++++++++++++++++
3 files changed, 134 insertions(+), 11 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
index fc22e36a67c54..732b5f199230f 100644
--- a/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/InconsistentIfElseBracesCheck.cpp
@@ -18,21 +18,14 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
-/// Look through AttributedStmt wrappers to find the underlying statement.
-static const Stmt *ignoreAttributed(const Stmt *S) {
- if (const auto *AS = dyn_cast<AttributedStmt>(S))
- return AS->getSubStmt();
- return S;
-}
-
/// 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 = ignoreAttributed(If->getThen());
+ const Stmt *const Then = If->getThen()->stripLabelLikeStatements();
if (isa<CompoundStmt>(Then))
return true;
if (const Stmt *Else = If->getElse()) {
- Else = ignoreAttributed(Else);
+ Else = Else->stripLabelLikeStatements();
if (const auto *NestedIf = dyn_cast<const IfStmt>(Else))
return shouldHaveBraces(NestedIf);
@@ -61,7 +54,7 @@ void InconsistentIfElseBracesCheck::check(
void InconsistentIfElseBracesCheck::checkIfStmt(
const MatchFinder::MatchResult &Result, const IfStmt *If) {
- const Stmt *Then = ignoreAttributed(If->getThen());
+ const Stmt *Then = If->getThen()->stripLabelLikeStatements();
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.
@@ -74,7 +67,7 @@ void InconsistentIfElseBracesCheck::checkIfStmt(
}
if (const Stmt *Else = If->getElse()) {
- Else = ignoreAttributed(Else);
+ Else = Else->stripLabelLikeStatements();
if (const auto *NestedIf = dyn_cast<const IfStmt>(Else))
checkIfStmt(Result, NestedIf);
else if (!isa<CompoundStmt>(Else))
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index c369b1fd8b373..003b622e6821a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -780,6 +780,10 @@ Changes in existing checks
- Fixed a false positive where ``bool`` conditions in C conditional
operators were diagnosed as implicit conversions to ``int``.
+- Improved :doc:`readability-inconsistent-ifelse-braces
+ <clang-tidy/checks/readability/inconsistent-ifelse-braces>` check to
+ correctly handle labeled statements of ``if``/``else`` bodies.
+
- Improved :doc:`readability-non-const-parameter
<clang-tidy/checks/readability/non-const-parameter>` check:
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
new file mode 100644
index 0000000000000..fcf9b1112a122
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
@@ -0,0 +1,126 @@
+// RUN: %check_clang_tidy -std=c++98-or-later %s readability-inconsistent-ifelse-braces %t
+
+// Positive tests.
+void f(bool b) {
+ if (b) goo:
+ return;
+ else too: {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { goo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else too: {
+
+ if (b) xoo: {
+ return;
+ } else yoo:
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { yoo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
+
+ if (b) hoo: {
+ return;
+ } else loo: [[unlikely]]
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { loo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
+
+ if (b)
+ return;
+ else coo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) {
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else coo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) aoo:
+ return;
+ else boo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { aoo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else boo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) moo: [[unlikely]]
+ return;
+ else noo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { moo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else noo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) poo: [[likely]] {
+ return;
+ } else qoo: [[unlikely]]
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { qoo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
+}
+
+
+// Negative tests.
+void g(bool b) {
+ if (b) {
+ return;
+ } else foo: {
+ return;
+ }
+
+ if (b) {
+ return;
+ } else goo: [[unlikely]] {
+ return;
+ }
+
+ if (b) {
+ return;
+ } else hoo: {
+ return;
+ }
+
+ if (b) joo: {
+ return;
+ } else {
+ return;
+ }
+
+ if (b) roo: [[unlikely]] {
+ return;
+ } else {
+ return;
+ }
+
+ if (b) koo: {
+ return;
+ } else loo: {
+ return;
+ }
+
+ if (b) moo:
+ return;
+ else noo:
+ return;
+
+ if (b)
+ return;
+ else ooo:
+ return;
+
+ if (b) poo: [[likely]]
+ return;
+ else qoo: [[unlikely]]
+ return;
+}
>From b1c807de5a867b961b1ebd26e1fb5ef71dddcd7b Mon Sep 17 00:00:00 2001
From: Gaurav Dhingra <gauravdhingra.gxyd at gmail.com>
Date: Thu, 11 Jun 2026 14:43:19 +0530
Subject: [PATCH 2/2] moves tests to appropriate test files
---
.../inconsistent-ifelse-braces-attributes.cpp | 65 +++++++++
.../inconsistent-ifelse-braces.cpp | 54 ++++++++
.../inconsistent-ifelse-labels.cpp | 126 ------------------
3 files changed, 119 insertions(+), 126 deletions(-)
delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
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 01965116c3272..3aab8e75287f0 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
@@ -28,6 +28,54 @@ void f(bool b) {
// CHECK-MESSAGES: :[[@LINE-4]]:20: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: if (b) {{[[][[]}}likely{{[]][]]}} {
// CHECK-FIXES: } else {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) hoo: {
+ return;
+ } else loo: [[unlikely]]
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { loo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
+
+ if (b)
+ return;
+ else coo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) {
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else coo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) aoo:
+ return;
+ else boo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { aoo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else boo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) moo: [[unlikely]]
+ return;
+ else noo: [[unlikely]] {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (b) { moo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else noo: {{[[][[]}}unlikely{{[]][]]}} {
+
+ if (b) poo: [[likely]] {
+ return;
+ } else qoo: [[unlikely]]
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { qoo: {{[[][[]}}unlikely{{[]][]]}}
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
}
// Negative tests.
@@ -85,4 +133,21 @@ void g(bool b) {
} else [[unlikely]] [[unlikely]] {
return;
}
+
+ if (b) {
+ return;
+ } else goo: [[unlikely]] {
+ return;
+ }
+
+ if (b) roo: [[unlikely]] {
+ return;
+ } else {
+ return;
+ }
+
+ if (b) poo: [[likely]]
+ return;
+ else qoo: [[unlikely]]
+ 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 3874719512f91..5023237ae3b02 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
@@ -116,6 +116,26 @@ void f() {
} else MACRO_FUN;
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
// CHECK-FIXES: } else { MACRO_FUN;
+
+ if (cond("if0")) goo:
+ return;
+ else too: {
+ return;
+ }
+ // CHECK-MESSAGES: :[[@LINE-5]]:19: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: if (cond("if0")) { goo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: } else too: {
+
+ if (cond("if0")) xoo: {
+ return;
+ } else yoo:
+ return;
+ // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
+ // CHECK-FIXES: } else { yoo:
+ // CHECK-FIXES-NEXT: return;
+ // CHECK-FIXES-NEXT: }
+
}
// Negative tests.
@@ -134,4 +154,38 @@ void g() {
do_something("elseif-single-line");
else
do_something("else-single-line");
+
+ if (cond("if2")) {
+ return;
+ } else foo: {
+ return;
+ }
+
+ if (cond("if3")) {
+ return;
+ } else hoo: {
+ return;
+ }
+
+ if (cond("if4")) joo: {
+ return;
+ } else {
+ return;
+ }
+
+ if (cond("if5")) koo: {
+ return;
+ } else loo: {
+ return;
+ }
+
+ if (cond("if6")) moo:
+ return;
+ else noo:
+ return;
+
+ if (cond("if7"))
+ return;
+ else ooo:
+ return;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
deleted file mode 100644
index fcf9b1112a122..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/inconsistent-ifelse-labels.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-// RUN: %check_clang_tidy -std=c++98-or-later %s readability-inconsistent-ifelse-braces %t
-
-// Positive tests.
-void f(bool b) {
- if (b) goo:
- return;
- else too: {
- return;
- }
- // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: if (b) { goo:
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: } else too: {
-
- if (b) xoo: {
- return;
- } else yoo:
- return;
- // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: } else { yoo:
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: }
-
- if (b) hoo: {
- return;
- } else loo: [[unlikely]]
- return;
- // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: } else { loo: {{[[][[]}}unlikely{{[]][]]}}
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: }
-
- if (b)
- return;
- else coo: [[unlikely]] {
- return;
- }
- // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: if (b) {
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: } else coo: {{[[][[]}}unlikely{{[]][]]}} {
-
- if (b) aoo:
- return;
- else boo: [[unlikely]] {
- return;
- }
- // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: if (b) { aoo:
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: } else boo: {{[[][[]}}unlikely{{[]][]]}} {
-
- if (b) moo: [[unlikely]]
- return;
- else noo: [[unlikely]] {
- return;
- }
- // CHECK-MESSAGES: :[[@LINE-5]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: if (b) { moo: {{[[][[]}}unlikely{{[]][]]}}
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: } else noo: {{[[][[]}}unlikely{{[]][]]}} {
-
- if (b) poo: [[likely]] {
- return;
- } else qoo: [[unlikely]]
- return;
- // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: statement should have braces [readability-inconsistent-ifelse-braces]
- // CHECK-FIXES: } else { qoo: {{[[][[]}}unlikely{{[]][]]}}
- // CHECK-FIXES-NEXT: return;
- // CHECK-FIXES-NEXT: }
-}
-
-
-// Negative tests.
-void g(bool b) {
- if (b) {
- return;
- } else foo: {
- return;
- }
-
- if (b) {
- return;
- } else goo: [[unlikely]] {
- return;
- }
-
- if (b) {
- return;
- } else hoo: {
- return;
- }
-
- if (b) joo: {
- return;
- } else {
- return;
- }
-
- if (b) roo: [[unlikely]] {
- return;
- } else {
- return;
- }
-
- if (b) koo: {
- return;
- } else loo: {
- return;
- }
-
- if (b) moo:
- return;
- else noo:
- return;
-
- if (b)
- return;
- else ooo:
- return;
-
- if (b) poo: [[likely]]
- return;
- else qoo: [[unlikely]]
- return;
-}
More information about the cfe-commits
mailing list