Skip to content

Commit dc3be6c

Browse files
cor3ntinIanWood1
authored andcommitted
[Clang] incorrect assertion when checking template template parameter of a lambda (llvm#138121)
When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
1 parent 6df4bce commit dc3be6c

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,8 @@ Bug Fixes to C++ Support
621621
- Clang now issues an error when placement new is used to modify a const-qualified variable
622622
in a ``constexpr`` function. (#GH131432)
623623
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
624+
- Fix a crash when checking the template template parameters of a dependent lambda appearing in an alias declaration.
625+
(#GH136432), (#GH137014), (#GH138018)
624626

625627
Bug Fixes to AST Handling
626628
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/DeclCXX.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,11 @@ static NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) {
16961696
RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
16971697

16981698
DeclContext::lookup_result Calls = RD.lookup(Name);
1699-
assert(!Calls.empty() && "Missing lambda call operator!");
1699+
1700+
// This can happen while building the lambda.
1701+
if (Calls.empty())
1702+
return nullptr;
1703+
17001704
assert(allLookupResultsAreTheSame(Calls) &&
17011705
"More than one lambda call operator!");
17021706

@@ -1750,6 +1754,7 @@ CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator() const {
17501754

17511755
CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
17521756
CXXMethodDecl *CallOp = getLambdaCallOperator();
1757+
assert(CallOp && "null call operator");
17531758
CallingConv CC = CallOp->getType()->castAs<FunctionType>()->getCallConv();
17541759
return getLambdaStaticInvoker(CC);
17551760
}

clang/test/SemaCXX/lambda-unevaluated.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,19 @@ void func() {
266266
}
267267

268268
} // namespace GH88081
269+
270+
namespace GH138018 {
271+
272+
template <typename T> struct vec {};
273+
274+
auto structure_to_typelist(auto) {
275+
return []<template <typename> typename T>(T<int>) {
276+
return 0;
277+
}(vec<int>{});
278+
}
279+
280+
template <typename T> using helper = decltype(structure_to_typelist(T{}));
281+
static_assert(__is_same_as(int, helper<int>));
282+
283+
284+
} // namespace GH138018

0 commit comments

Comments
 (0)