[clang] [clang-format] Stop treating the new expression as a lambda (PR #223266)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 13 11:34:03 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: sstwcw
<details>
<summary>Changes</summary>
before
```C++
x = new a *[] { nullptr };
x = new a *[] {
nullptr, //
nullptr,
};
```
after
```C++
x = new a *[]{nullptr};
x = new a *[]{
nullptr, //
nullptr,
};
```
Fixes #<!-- -->38820.
The program previously treated the part starting with the square brackets as a lambda when the type ended in a star.
---
Full diff: https://github.com/llvm/llvm-project/pull/223266.diff
3 Files Affected:
- (modified) clang/lib/Format/UnwrappedLineParser.cpp (+21-1)
- (modified) clang/unittests/Format/FormatTest.cpp (+10)
- (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+10)
``````````diff
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index ac3eb6fa5bcf54..ddef3ba5ce9090 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -2473,7 +2473,25 @@ bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
nextToken();
if (Previous) {
const auto *PrevPrev = Previous->getPreviousNonComment();
- if (Previous->is(tok::star) && PrevPrev && PrevPrev->isTypeName(LangOpts))
+ // The star may be part of the type in a trailing return type or new
+ // expression. Then the square brackets will mean array instead of capture.
+ auto StarIsType = [&]() {
+ if (!PrevPrev)
+ return false;
+ if (PrevPrev->isTypeName(LangOpts))
+ return true;
+ if (PrevPrev->isNot(tok::identifier))
+ return false;
+ const auto *Tok = PrevPrev->getPreviousNonComment();
+ // Skip the placement part of the new expression.
+ if (Tok && Tok->is(tok::r_paren)) {
+ Tok = Tok->MatchingParen;
+ if (Tok)
+ Tok = Tok->getPreviousNonComment();
+ }
+ return Tok && Tok->is(tok::kw_new);
+ };
+ if (Previous->is(tok::star) && StarIsType())
return false;
if (Previous->closesScope()) {
// Not a potential C-style cast.
@@ -2753,6 +2771,8 @@ bool UnwrappedLineParser::parseParens(TokenType StarAndAmpTokenType,
FormatTok->setBlockKind(BK_BracedInit);
}
}
+ RParen->MatchingParen = LParen;
+ LParen->MatchingParen = RParen;
return SeenEqual;
}
case tok::r_brace:
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 5aed37aa56d524..57d5d3ed1914d1 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -12303,6 +12303,16 @@ TEST_F(FormatTest, UnderstandsNewAndDelete) {
" p->delete ();\n"
"}");
+ verifyFormat("x = new a *[]{nullptr};");
+ verifyFormat("x = new (a) a *[]{\n"
+ " nullptr, //\n"
+ " nullptr,\n"
+ "};");
+ verifyFormat("x = new a *[]{\n"
+ " nullptr, //\n"
+ " nullptr,\n"
+ "};");
+
FormatStyle AfterPlacementOperator = getLLVMStyle();
AfterPlacementOperator.SpaceBeforeParens = FormatStyle::SBPO_Custom;
EXPECT_TRUE(
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index f5ff5229f7232a..a6f5af43f57996 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2459,6 +2459,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsLambdas) {
EXPECT_TOKEN(Tokens[3], tok::star, TT_BinaryOperator);
EXPECT_TOKEN(Tokens[4], tok::l_square, TT_LambdaLSquare);
EXPECT_TOKEN(Tokens[6], tok::l_brace, TT_LambdaLBrace);
+
+ // The new declarator is not a lambda.
+ Tokens = annotate("x = new a *[]{};");
+ ASSERT_EQ(Tokens.size(), 11u) << Tokens;
+ EXPECT_TOKEN(Tokens[4], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[5], tok::l_square, TT_ArraySubscriptLSquare);
+ Tokens = annotate("x = new (a) a *[]{};");
+ ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+ EXPECT_TOKEN(Tokens[7], tok::star, TT_PointerOrReference);
+ EXPECT_TOKEN(Tokens[8], tok::l_square, TT_ArraySubscriptLSquare);
}
TEST_F(TokenAnnotatorTest, UnderstandsFunctionAnnotations) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/223266
More information about the cfe-commits
mailing list