https://github.com/SamrudhNelli created 
https://github.com/llvm/llvm-project/pull/180690

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.
Fixes #180460 

>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] [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

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

Reply via email to