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
