diff options
| author | Daniel M. Katz <katzdm@gmail.com> | 2025-11-22 22:11:58 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-23 11:11:58 +0800 |
| commit | 525e68e9e9a44e88eb88ef2d6f058a482972c989 (patch) | |
| tree | 11ab6855bfc08c95fe022ea3cd146a54dcc094a8 | |
| parent | 0859ac5866a0228f5607dd329f83f4a9622dedcc (diff) | |
Don't mark lambda non-dependent if nested in a generic lambda. (#149121)
Fixes #118187
Fixes #156579
An instantiated `LambdaExpr` can currently be marked as
`LDK_NeverDependent` if it's nested within a generic lambda. If that
`LambdaExpr` in fact depends on template parameters introduced by the
enclosing generic lambda, then its dependence will be misreported as
"never dependent" and spurious diagnostics can result.
The fix here proposed is a bit ugly, but the condition that it's being
bolted onto already seems like a bit of a hack, so this seems no worse
for wear.
Note that #89702 surfaced this change because it caused the inner lambda
expression to (correctly) be considered in a constant-evaluated context.
The affected check for whether to mark the inner lambda as
`LDK_NeverDependent` therefore started to apply, whereas it didn't
before.
**Tested**: `check-clang` and `check-cxx`.
| -rw-r--r-- | clang/docs/ReleaseNotes.rst | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx2a-consteval.cpp | 23 |
3 files changed, 25 insertions, 1 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 63930f43c25e..8161ccdffca8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -557,6 +557,7 @@ Bug Fixes to C++ Support - Diagnose unresolved overload sets in non-dependent compound requirements. (#GH51246) (#GH97753) - Fix a crash when extracting unavailable member type from alias in template deduction. (#GH165560) - Fix incorrect diagnostics for lambdas with init-captures inside braced initializers. (#GH163498) +- Fixed spurious diagnoses of certain nested lambda expressions. (#GH149121) (#GH156579) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c2491489f40d..0e8b674a006d 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -15628,6 +15628,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { DC = DC->getParent(); if ((getSema().isUnevaluatedContext() || getSema().isConstantEvaluatedContext()) && + !(dyn_cast_or_null<CXXRecordDecl>(DC->getParent()) && + cast<CXXRecordDecl>(DC->getParent())->isGenericLambda()) && (DC->isFileContext() || !DC->getParent()->isDependentContext())) DependencyKind = CXXRecordDecl::LDK_NeverDependent; diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 1474c48cda3c..92bfa40caec4 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -1319,6 +1319,27 @@ namespace GH139160{ B result = (B){10, get_value(make_struct())}; // expected-error {{initializer element is not a compile-time constant}} // expected-error@-1 {{call to consteval function 'GH139160::get_value' is not a constant expression}} // expected-note@-2 {{non-constexpr function 'make_struct' cannot be used in a constant expression}} -}; +} // namespace GH139160 + +namespace GH118187 { + +template <typename T> int t() { + return []<typename U>() consteval { + return [](U v) { return v; }(123); + }.template operator()<int>(); +} +int v = t<int>(); +} // namespace GH118187 +namespace GH156579 { +template <class> +auto f{[] (auto...) { + if constexpr ([] (auto) { return true; }(0)) + return 0; +}}; + +void g() { + f<int>(); +} +} // namespace GH156579 |
