[clang] de03ec7 - [Clang] Fix incorrect mutability of decltype((x)) in lambda return types (#180690)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 17 12:37:07 PST 2026
Author: Samrudh Nelli
Date: 2026-02-17T21:37:03+01:00
New Revision: de03ec740b22485e2b84234abbfdc3e67592b946
URL: https://github.com/llvm/llvm-project/commit/de03ec740b22485e2b84234abbfdc3e67592b946
DIFF: https://github.com/llvm/llvm-project/commit/de03ec740b22485e2b84234abbfdc3e67592b946.diff
LOG: [Clang] Fix incorrect mutability of decltype((x)) in lambda return types (#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
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Parse/ParseExprCXX.cpp
clang/test/SemaCXX/lambda-expressions.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5416b25b3927c..86cee7d1b6f9b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -283,6 +283,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)
- Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type vectors in ``constexpr``. (#GH180044)
Bug Fixes to AST Handling
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 842b52375eb14..b3d50daf66b10 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1417,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].
@@ -1445,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);
}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index f9d7cfcbbd18d..00c52efb78a7d 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}}
+ };
+}
+}
More information about the cfe-commits
mailing list