https://github.com/a-tarasyuk updated 
https://github.com/llvm/llvm-project/pull/166180

>From b97e99f73cddc4ca5c525dbd9e781679902adaec Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <[email protected]>
Date: Mon, 3 Nov 2025 17:21:38 +0200
Subject: [PATCH] [Clang] fix confusing diagnostics for lambdas with
 init-captures inside braced initializers

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/Parse/ParseExprCXX.cpp              | 42 +++++++++++--------
 .../lambda-misplaced-capture-default.cpp      |  9 ++++
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92fc9381a5868..63faf46895989 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -496,6 +496,7 @@ Bug Fixes to C++ Support
   nontrivial member when another member has an initializer. (#GH81774)
 - Fixed a template depth issue when parsing lambdas inside a type constraint. 
(#GH162092)
 - Diagnose unresolved overload sets in non-dependent compound requirements. 
(#GH51246) (#GH97753)
+- Fix incorrect diagnostics for lambdas with init-captures inside braced 
initializers. (#GH163498)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 74f87a8cb63c3..03ae727168df0 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -772,9 +772,10 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
 
   // Produce a diagnostic if we're not tentatively parsing; otherwise track
   // that our parse has failed.
-  auto Invalid = [&](llvm::function_ref<void()> Action) {
+  auto Result = [&](llvm::function_ref<void()> Action,
+                    LambdaIntroducerTentativeParse State) {
     if (Tentative) {
-      *Tentative = LambdaIntroducerTentativeParse::Invalid;
+      *Tentative = State;
       return false;
     }
     Action();
@@ -824,9 +825,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
           break;
         }
 
-        return Invalid([&] {
-          Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
-        });
+        return Result(
+            [&] {
+              Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
+            },
+            LambdaIntroducerTentativeParse::Invalid);
       }
       ConsumeToken();
     }
@@ -861,9 +864,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
         ConsumeToken();
         Kind = LCK_StarThis;
       } else {
-        return Invalid([&] {
-          Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
-        });
+        return Result(
+            [&] {
+              Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
+            },
+            LambdaIntroducerTentativeParse::Invalid);
       }
     } else if (Tok.is(tok::kw_this)) {
       Kind = LCK_This;
@@ -875,8 +880,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
       // or the start of a capture (in the "&" case) with the rest of the
       // capture missing. Both are an error but a misplaced capture-default
       // is more likely if we don't already have a capture default.
-      return Invalid(
-          [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });
+      return Result(
+          [&] { Diag(Tok.getLocation(), diag::err_capture_default_first); },
+          LambdaIntroducerTentativeParse::Incomplete);
     } else {
       TryConsumeToken(tok::ellipsis, EllipsisLocs[0]);
 
@@ -899,14 +905,16 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer 
&Intro,
         Id = Tok.getIdentifierInfo();
         Loc = ConsumeToken();
       } else if (Tok.is(tok::kw_this)) {
-        return Invalid([&] {
-          // FIXME: Suggest a fixit here.
-          Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
-        });
+        return Result(
+            [&] {
+              // FIXME: Suggest a fixit here.
+              Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
+            },
+            LambdaIntroducerTentativeParse::Invalid);
       } else {
-        return Invalid([&] {
-          Diag(Tok.getLocation(), diag::err_expected_capture);
-        });
+        return Result(
+            [&] { Diag(Tok.getLocation(), diag::err_expected_capture); },
+            LambdaIntroducerTentativeParse::Invalid);
       }
 
       TryConsumeToken(tok::ellipsis, EllipsisLocs[2]);
diff --git a/clang/test/Parser/lambda-misplaced-capture-default.cpp 
b/clang/test/Parser/lambda-misplaced-capture-default.cpp
index d65b875102da7..4f5bd6d7fa5e9 100644
--- a/clang/test/Parser/lambda-misplaced-capture-default.cpp
+++ b/clang/test/Parser/lambda-misplaced-capture-default.cpp
@@ -36,3 +36,12 @@ template <typename... Args> void Test(Args... args) {
   [... xs = &args, &] {};  // expected-error {{capture default must be first}}
 }
 } // namespace misplaced_capture_default_pack
+
+namespace GH163498 {
+struct S {
+  template <class T> S(T) {}
+};
+void t() {
+  S s{[a(42), &] {}}; // expected-error {{capture default must be first}}
+}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to