[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