From 4287fc38935f69a2b3745ddc82a526cde93f38d5 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Sat, 11 Oct 2025 23:12:36 +0800 Subject: [PATCH 1/4] [clang-format] Fix formatting of requires expressions in braced initializers When clang-format encountered a requires expression inside a braced initializer (e.g., `bool foo{requires { 0; }};`), it would incorrectly format the code to the following: bool bar{requires {0; } } ; The issue was that UnwrappedLineParser::parseBracedList had no explicit handling for the requires keyword, so it would just call nextToken() instead of properly parsing the requires expression. This fix adds a case for tok::kw_requires in parseBracedList, calling parseRequiresExpression to handle it correctly, matching the existing behavior in parseParens [1]. Fixes https://github.com/llvm/llvm-project/issues/162984. [1]: https://github.com/llvm/llvm-project/blob/7eee67202378932d03331ad04e7d07ed4d988381/clang/lib/Format/UnwrappedLineParser.cpp#L2713-L2718 Signed-off-by: Ruoyu Zhong --- clang/lib/Format/UnwrappedLineParser.cpp | 6 ++++++ clang/unittests/Format/FormatTest.cpp | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 28797433e06e3..dec71191d7356 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2569,6 +2569,12 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { if (IsEnum && !Style.AllowShortEnumsOnASingleLine) addUnwrappedLine(); break; + case tok::kw_requires: { + auto *RequiresToken = FormatTok; + nextToken(); + parseRequiresExpression(RequiresToken); + break; + } default: nextToken(); break; diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index fef70365b5e18..5a8056e310d45 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -26973,6 +26973,12 @@ TEST_F(FormatTest, RequiresExpressionIndentation) { Style); } +TEST_F(FormatTest, RequiresExpressionInBracedInitializer) { + verifyFormat("bool foo{requires { 0; }};"); + verifyFormat("int bar{requires(T t) { t.f(); }};"); + verifyFormat("auto baz{requires { typename T::type; } && true};"); +} + TEST_F(FormatTest, StatementAttributeLikeMacros) { FormatStyle Style = getLLVMStyle(); StringRef Source = "void Foo::slot() {\n" From 56c49be38b2f26ee1c151b8a83629693fcdf17cc Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Sun, 12 Oct 2025 03:08:16 +0800 Subject: [PATCH 2/4] [clang-format] Add a token annotator test for requires expression in braced initializer --- clang/unittests/Format/TokenAnnotatorTest.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index c21b118847d99..fe2d184761fd8 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1490,6 +1490,12 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) { EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); + Tokens = annotate("int bar{requires(int i) { i + 5; }};"); + ASSERT_EQ(Tokens.size(), 17u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); + EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); + EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); + Tokens = annotate("if (requires(int i) { i + 5; }) return;"); ASSERT_EQ(Tokens.size(), 17u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::kw_requires, TT_RequiresExpression); From aa6dae134cf11b9712e9d686e37500ccf0c03207 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Sun, 12 Oct 2025 13:37:02 +0800 Subject: [PATCH 3/4] [clang-format] Drop format test for requires expression in braced initializer --- clang/unittests/Format/FormatTest.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 5a8056e310d45..fef70365b5e18 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -26973,12 +26973,6 @@ TEST_F(FormatTest, RequiresExpressionIndentation) { Style); } -TEST_F(FormatTest, RequiresExpressionInBracedInitializer) { - verifyFormat("bool foo{requires { 0; }};"); - verifyFormat("int bar{requires(T t) { t.f(); }};"); - verifyFormat("auto baz{requires { typename T::type; } && true};"); -} - TEST_F(FormatTest, StatementAttributeLikeMacros) { FormatStyle Style = getLLVMStyle(); StringRef Source = "void Foo::slot() {\n" From e836a16bea95e65a6327ff0c5fc66266c0cdd4e3 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Sun, 12 Oct 2025 13:39:37 +0800 Subject: [PATCH 4/4] [clang-format] Update token annotator test for requires expression in braced initializer Co-authored-by: Owen Pan --- clang/unittests/Format/TokenAnnotatorTest.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index fe2d184761fd8..1152466b0179f 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1490,11 +1490,10 @@ TEST_F(TokenAnnotatorTest, UnderstandsRequiresExpressions) { EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); - Tokens = annotate("int bar{requires(int i) { i + 5; }};"); - ASSERT_EQ(Tokens.size(), 17u) << Tokens; + Tokens = annotate("bool foo{requires { 0; }};"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; EXPECT_TOKEN(Tokens[3], tok::kw_requires, TT_RequiresExpression); - EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_RequiresExpressionLParen); - EXPECT_TOKEN(Tokens[8], tok::l_brace, TT_RequiresExpressionLBrace); + EXPECT_TOKEN(Tokens[4], tok::l_brace, TT_RequiresExpressionLBrace); Tokens = annotate("if (requires(int i) { i + 5; }) return;"); ASSERT_EQ(Tokens.size(), 17u) << Tokens;