[Clang] Correctly determine constexprness of dependent lambdas. (#124468)

We skipped checking if a lambda is constexpr if the parent context was
dependent, even if the lambda itself wasn't (and there is no other
opportunity to establish constexprness)


Fixes #114234
Fixes #97958
This commit is contained in:
cor3ntin 2025-01-26 16:17:21 +01:00 committed by GitHub
parent dec47b76f4
commit e4514293f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 7 deletions

View File

@ -991,6 +991,7 @@ Bug Fixes to C++ Support
- Fixed assertions or false compiler diagnostics in the case of C++ modules for
lambda functions or inline friend functions defined inside templates (#GH122493).
- Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423)
- Correctly determine the implicit constexprness of lambdas in dependent contexts. (#GH97958) (#GH114234)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -2239,18 +2239,18 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
Cleanup.mergeFrom(LambdaCleanup);
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
CaptureDefault, CaptureDefaultLoc,
ExplicitParams, ExplicitResultType,
CaptureInits, EndLoc,
ContainsUnexpandedParameterPack);
LambdaExpr *Lambda =
LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault,
CaptureDefaultLoc, ExplicitParams, ExplicitResultType,
CaptureInits, EndLoc, ContainsUnexpandedParameterPack);
// If the lambda expression's call operator is not explicitly marked constexpr
// and we are not in a dependent context, analyze the call operator to infer
// and is not dependent, analyze the call operator to infer
// its constexpr-ness, suppressing diagnostics while doing so.
if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() &&
!CallOperator->isConstexpr() &&
!isa<CoroutineBodyStmt>(CallOperator->getBody()) &&
!Class->getDeclContext()->isDependentContext()) {
!Class->isDependentContext()) {
CallOperator->setConstexprKind(
CheckConstexprFunctionDefinition(CallOperator,
CheckConstexprKind::CheckValid)

View File

@ -349,3 +349,27 @@ static_assert(OtherCaptures(), "");
} // namespace PR36054
#endif // ndef CPP14_AND_EARLIER
#if __cpp_constexpr >= 201907L
namespace GH114234 {
template <auto Arg>
auto g() { return Arg; }
template <typename>
auto f() {
[]<typename>() {
g<[] { return 123; }()>();
}.template operator()<int>();
}
void test() { f<int>(); }
}
namespace GH97958 {
static_assert(
[]<int I=0>() -> decltype([]{ return true; })
{ return {}; }()());
}
#endif