[clang] [Clang] prevent assertion failure by avoiding always-dependent lambdas in constraint-related nested scopes (PR #173776)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 28 06:50:04 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Oleksandr T. (a-tarasyuk)
<details>
<summary>Changes</summary>
Fixes #<!-- -->172814
---
This patch resolves an issue in which a lambda could be classified as always-dependent while traversing nested scopes, causing an assertion failure during capture handling.
Changes in PR #<!-- -->93206 expanded scope-based dependency handling in a way that could mark certain lambdas as always-dependent when no template-dependent context was present.
This update refines the criteria for assigning `LambdaDependencyKind::LDK_AlwaysDependent` and applies it only after traversal reaches a distinct enclosing function scope with template-dependent parameters.
---
Full diff: https://github.com/llvm/llvm-project/pull/173776.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+1)
- (modified) clang/lib/Sema/SemaLambda.cpp (+9-5)
- (modified) clang/test/SemaCXX/lambda-unevaluated.cpp (+8-1)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2319ff13f7864..1ae44bf610221 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -623,6 +623,7 @@ Bug Fixes to C++ Support
- Fix the result of ``__is_pointer_interconvertible_base_of`` when arguments are qualified and passed via template parameters. (#GH135273)
- Fixed a crash when evaluating nested requirements in requires-expressions that reference invented parameters. (#GH166325)
- Fixed a crash when standard comparison categories (e.g. ``std::partial_ordering``) are defined with incorrect static member types. (#GH170015) (#GH56571)
+- Fixed an assertion failure triggered by nested lambdas during capture handling. (#GH172814)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 81ec0b18dedfd..53f2612a46bf4 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1102,7 +1102,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
CXXRecordDecl::LDK_Unknown;
if (CurScope->getTemplateParamParent() != nullptr) {
LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent;
- } else if (Scope *P = CurScope->getParent()) {
+ } else if (Scope *ParentScope = CurScope->getParent()) {
// Given a lambda defined inside a requires expression,
//
// struct S {
@@ -1113,10 +1113,14 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
// The parameter var is not injected into the function Decl at the point of
// parsing lambda. In such scenarios, perceiving it as dependent could
// result in the constraint being evaluated, which matches what GCC does.
- while (P->getEntity() && P->getEntity()->isRequiresExprBody())
- P = P->getParent();
- if (P->isFunctionDeclarationScope() &&
- llvm::any_of(P->decls(), [](Decl *D) {
+ Scope *LookupScope = ParentScope;
+ while (LookupScope->getEntity() &&
+ LookupScope->getEntity()->isRequiresExprBody())
+ LookupScope = LookupScope->getParent();
+
+ if (LookupScope != ParentScope &&
+ LookupScope->isFunctionDeclarationScope() &&
+ llvm::any_of(LookupScope->decls(), [](Decl *D) {
return isa<ParmVarDecl>(D) &&
cast<ParmVarDecl>(D)->getType()->isTemplateTypeParmType();
}))
diff --git a/clang/test/SemaCXX/lambda-unevaluated.cpp b/clang/test/SemaCXX/lambda-unevaluated.cpp
index 9289fc9ec1243..e3dffa00cd39a 100644
--- a/clang/test/SemaCXX/lambda-unevaluated.cpp
+++ b/clang/test/SemaCXX/lambda-unevaluated.cpp
@@ -1,7 +1,6 @@
// RUN: %clang_cc1 -std=c++20 %s -Wno-c++23-extensions -verify
// RUN: %clang_cc1 -std=c++23 %s -verify
-
template <auto> struct Nothing {};
Nothing<[]() { return 0; }()> nothing;
@@ -282,3 +281,11 @@ static_assert(__is_same_as(int, helper<int>));
} // namespace GH138018
+
+namespace GH172814 {
+auto t() {
+ int x = 0;
+ return [](auto w=[&] { x += w(); }); // expected-error {{lambda expression in default argument cannot capture any entity}} \
+ // expected-error {{expected body of lambda expression}}
+};
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/173776
More information about the cfe-commits
mailing list