https://github.com/SamrudhNelli updated https://github.com/llvm/llvm-project/pull/180690
>From e6344701149989a2f40973c6b76c7b2fb398215c Mon Sep 17 00:00:00 2001 From: Samrudh Nelli <[email protected]> Date: Tue, 10 Feb 2026 12:32:45 +0530 Subject: [PATCH 1/2] [Clang] Fix incorrect mutability of decltype((x)) in lambda return types Previously, the parser did not update the lambda's mutability state before parsing the trailing return type. This caused decltype((x)) to incorrectly deduce a non-const reference even in a non-mutable lambda. --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Parse/ParseExprCXX.cpp | 3 +++ clang/test/SemaCXX/lambda-expressions.cpp | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a1bb1bd2467b7..f7a1a97cc1caf 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -262,6 +262,8 @@ Bug Fixes to C++ Support - Fixed a crash when instantiating ``requires`` expressions involving substitution failures in C++ concepts. (#GH176402) - Fixed a crash when a default argument is passed to an explicit object parameter. (#GH176639) - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) +- Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable + when used inside decltype in the return type. (#GH180460) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 842b52375eb14..0fb050cce329c 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1383,6 +1383,9 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS); addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); + if (clang::sema::LambdaScopeInfo *LSI = Actions.getCurLambda()) { + LSI->Mutable = MutableLoc.isValid(); + } } Actions.ActOnLambdaClosureParameters(getCurScope(), ParamInfo); diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index f9d7cfcbbd18d..ee6ae81107082 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -799,3 +799,16 @@ template auto t::operator()<int>(int a) const; // expected-note {{in instantiati } #endif + +namespace GH180460 { +// Trailing return type incorrectly treated 'x' as mutable. +void test_lambda_return_type() { + float x = 0.0f; + + [=]() -> decltype((x)) { + decltype(x) y1 = x; + decltype((x)) y2 = y1; // expected-note{{binding reference variable 'y2' here}} + return y2; // expected-warning{{reference to stack memory associated with local variable 'y1' returned}} + }; +} +} \ No newline at end of file >From 6646e3a14897af28d4b6a7adbe0d1f9b8b756ab2 Mon Sep 17 00:00:00 2001 From: Samrudh Nelli <[email protected]> Date: Wed, 11 Feb 2026 00:17:00 +0530 Subject: [PATCH 2/2] fix: run ActonLambdaClosureQualifiers before parsing return type --- clang/lib/Parse/ParseExprCXX.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 0fb050cce329c..b3d50daf66b10 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1383,9 +1383,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS); addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS); - if (clang::sema::LambdaScopeInfo *LSI = Actions.getCurLambda()) { - LSI->Mutable = MutableLoc.isValid(); - } } Actions.ActOnLambdaClosureParameters(getCurScope(), ParamInfo); @@ -1420,6 +1417,11 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( ConsumeToken(); } + // We have called ActOnLambdaClosureQualifiers for parentheses-less cases + // above. + if (HasParentheses) + Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); + SourceLocation FunLocalRangeEnd = DeclEndLoc; // Parse trailing-return-type[opt]. @@ -1448,11 +1450,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( TrailingReturnType, TrailingReturnTypeLoc, &DS), std::move(Attributes), DeclEndLoc); - // We have called ActOnLambdaClosureQualifiers for parentheses-less cases - // above. - if (HasParentheses) - Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc); - if (HasParentheses && Tok.is(tok::kw_requires)) ParseTrailingRequiresClause(D); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
