[clang] [clang-format] Disable short blocks if brace is on the new line (PR #196021)
Rudolf Lovrenčić via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 11 04:28:35 PDT 2026
https://github.com/rudolflovrencic updated https://github.com/llvm/llvm-project/pull/196021
>From 801153dde9b7fed6fc6f6faad398a5482ee9a503 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rudolf=20Lovren=C4=8Di=C4=87?= <rudolf at lovrencic.xyz>
Date: Wed, 6 May 2026 10:00:04 +0200
Subject: [PATCH] [clang-format] AllowShortBlocksOnASingleLine is overridden by
If and Loop specific options
AllowShortLoopsOnASingleLine and AllowShortIfStatementsOnASingleLine now
override AllowShortBlocksOnASingleLine.
Fixes #183705 and #187993
---
clang/docs/ClangFormatStyleOptions.rst | 5 ++++
clang/include/clang/Format/Format.h | 5 ++++
clang/lib/Format/UnwrappedLineFormatter.cpp | 29 +++++++++++----------
clang/unittests/Format/FormatTest.cpp | 23 +++++++++++++---
4 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 7b1b7a7384b07..497c452aca41a 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -1827,6 +1827,11 @@ the configuration (without a prefix: ``Auto``).
Dependent on the value, ``while (true) { continue; }`` can be put on a
single line.
+ The construct-specific options ``AllowShortIfStatementsOnASingleLine`` and
+ ``AllowShortLoopsOnASingleLine`` take precedence over this option: an
+ ``if`` statement or a loop whose corresponding option disallows putting it
+ on a single line is not merged even when this option is ``Always``.
+
Possible values:
* ``SBS_Never`` (in configuration: ``Never``)
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 27b2d8f4a405b..ebcc416ba3af7 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -767,6 +767,11 @@ struct FormatStyle {
/// Dependent on the value, ``while (true) { continue; }`` can be put on a
/// single line.
+ ///
+ /// The construct-specific options ``AllowShortIfStatementsOnASingleLine`` and
+ /// ``AllowShortLoopsOnASingleLine`` take precedence over this option: an
+ /// ``if`` statement or a loop whose corresponding option disallows putting it
+ /// on a single line is not merged even when this option is ``Always``.
/// \version 3.5
ShortBlockStyle AllowShortBlocksOnASingleLine;
diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp
index 42eabc065b1a8..7847a8dcb40f7 100644
--- a/clang/lib/Format/UnwrappedLineFormatter.cpp
+++ b/clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -264,13 +264,10 @@ class LineJoiner {
: Limit - TheLine->Last->TotalLength;
if (TheLine->Last->is(TT_FunctionLBrace) &&
- TheLine->First == TheLine->Last) {
- const bool EmptyFunctionBody = NextLine.First->is(tok::r_brace);
- if ((EmptyFunctionBody && !Style.BraceWrapping.SplitEmptyFunction) ||
- (!EmptyFunctionBody &&
- Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Always)) {
- return tryMergeSimpleBlock(I, E, Limit);
- }
+ TheLine->First == TheLine->Last &&
+ !Style.BraceWrapping.SplitEmptyFunction &&
+ NextLine.First->is(tok::r_brace)) {
+ return tryMergeSimpleBlock(I, E, Limit);
}
// Try merging record blocks that have had their left brace wrapped into
@@ -647,11 +644,8 @@ class LineJoiner {
const bool IsEmptyBlock =
Line->Last->is(tok::l_brace) && NextLine->First->is(tok::r_brace);
- if ((IsEmptyBlock && !Style.BraceWrapping.SplitEmptyRecord) ||
- (!IsEmptyBlock &&
- Style.AllowShortBlocksOnASingleLine == FormatStyle::SBS_Always)) {
+ if (IsEmptyBlock && !Style.BraceWrapping.SplitEmptyRecord)
return tryMergeSimpleBlock(I, E, Limit);
- }
}
return 0;
@@ -895,6 +889,11 @@ class LineJoiner {
Line.startsWithExportBlock()) {
if (IsSplitBlock)
return 0;
+ // The construct-specific options AllowShortIfStatementsOnASingleLine and
+ // AllowShortLoopsOnASingleLine take precedence over
+ // AllowShortBlocksOnASingleLine: a statement whose specific option
+ // disallows merging is not put on a single line even when short blocks
+ // are always allowed.
// Don't merge when we can't except the case when
// the control statement block is empty
if (!Style.AllowShortIfStatementsOnASingleLine &&
@@ -988,9 +987,11 @@ class LineJoiner {
if (I[1]->Last->is(TT_LineComment))
return 0;
do {
- if (Tok->isOneOf(tok::l_brace, tok::r_brace) &&
- Tok->isNot(BK_BracedInit)) {
- return 0;
+ if (Tok->isOneOf(tok::l_brace, tok::r_brace)) {
+ const FormatToken *Open =
+ Tok->is(tok::l_brace) ? Tok : Tok->MatchingParen;
+ if (!Open || Open->isNot(BK_BracedInit))
+ return 0;
}
Tok = Tok->Next;
} while (Tok);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 6e1150227c452..e6ab1f23f4ef8 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -15560,11 +15560,24 @@ TEST_F(FormatTest, MergeShortFunctionBody) {
auto Style = getLLVMStyle();
Style.AllowShortFunctionsOnASingleLine = FormatStyle::ShortFunctionStyle();
Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Always;
+ Style.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_WithoutElse;
Style.BreakBeforeBraces = FormatStyle::BS_Custom;
Style.BraceWrapping.AfterFunction = true;
verifyFormat("int foo()\n"
- "{ return 1; }",
+ "{\n"
+ " return 1;\n"
+ "}\n",
+ Style);
+ verifyFormat("int foo()\n"
+ "{\n"
+ " if (true) { return 42; };\n"
+ "}\n",
+ Style);
+ verifyFormat("int foo()\n"
+ "{\n"
+ " static constexpr auto lambda = []() -> int { return 42; };\n"
+ "}\n",
Style);
}
@@ -15913,11 +15926,15 @@ TEST_F(FormatTest, AllowShortRecordOnASingleLine) {
Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Never;
verifyFormat("class foo\n"
- "{ int i; };",
+ "{\n"
+ " int i;\n"
+ "};",
Style);
Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Empty;
verifyFormat("class foo\n"
- "{ int i; };",
+ "{\n"
+ " int i;\n"
+ "};",
Style);
Style.AllowShortRecordOnASingleLine = FormatStyle::SRS_Always;
verifyFormat("class foo\n"
More information about the cfe-commits
mailing list