Skip to content

Commit e451429

Browse files
authored
[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
1 parent dec47b7 commit e451429

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,7 @@ Bug Fixes to C++ Support
991991
- Fixed assertions or false compiler diagnostics in the case of C++ modules for
992992
lambda functions or inline friend functions defined inside templates (#GH122493).
993993
- Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423)
994+
- Correctly determine the implicit constexprness of lambdas in dependent contexts. (#GH97958) (#GH114234)
994995

995996
Bug Fixes to AST Handling
996997
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaLambda.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,18 +2239,18 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
22392239

22402240
Cleanup.mergeFrom(LambdaCleanup);
22412241

2242-
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
2243-
CaptureDefault, CaptureDefaultLoc,
2244-
ExplicitParams, ExplicitResultType,
2245-
CaptureInits, EndLoc,
2246-
ContainsUnexpandedParameterPack);
2242+
LambdaExpr *Lambda =
2243+
LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault,
2244+
CaptureDefaultLoc, ExplicitParams, ExplicitResultType,
2245+
CaptureInits, EndLoc, ContainsUnexpandedParameterPack);
2246+
22472247
// If the lambda expression's call operator is not explicitly marked constexpr
2248-
// and we are not in a dependent context, analyze the call operator to infer
2248+
// and is not dependent, analyze the call operator to infer
22492249
// its constexpr-ness, suppressing diagnostics while doing so.
22502250
if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() &&
22512251
!CallOperator->isConstexpr() &&
22522252
!isa<CoroutineBodyStmt>(CallOperator->getBody()) &&
2253-
!Class->getDeclContext()->isDependentContext()) {
2253+
!Class->isDependentContext()) {
22542254
CallOperator->setConstexprKind(
22552255
CheckConstexprFunctionDefinition(CallOperator,
22562256
CheckConstexprKind::CheckValid)

clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,3 +349,27 @@ static_assert(OtherCaptures(), "");
349349
} // namespace PR36054
350350

351351
#endif // ndef CPP14_AND_EARLIER
352+
353+
354+
#if __cpp_constexpr >= 201907L
355+
namespace GH114234 {
356+
template <auto Arg>
357+
auto g() { return Arg; }
358+
359+
template <typename>
360+
auto f() {
361+
[]<typename>() {
362+
g<[] { return 123; }()>();
363+
}.template operator()<int>();
364+
}
365+
366+
void test() { f<int>(); }
367+
}
368+
369+
namespace GH97958 {
370+
static_assert(
371+
[]<int I=0>() -> decltype([]{ return true; })
372+
{ return {}; }()());
373+
}
374+
375+
#endif

0 commit comments

Comments
 (0)