Skip to content

Commit 376d5b0

Browse files
author
huqizhi
committed
[Clang][Sema] fix crash in codegen stage when an lambda expression declared in an unevaluated context
1 parent d7fb94b commit 376d5b0

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ Bug Fixes to C++ Support
210210
Fixes (`#68490 <https://github.com/llvm/llvm-project/issues/68490>`_)
211211
- Fix a crash when trying to call a varargs function that also has an explicit object parameter.
212212
Fixes (`#80971 ICE when explicit object parameter be a function parameter pack`)
213+
- Fix a crash in codegen when lambdas declared in an unevaluated context.
214+
Fixes (`#76674 <https://github.com/llvm/llvm-project/issues/76674>`_)
213215

214216
Bug Fixes to AST Handling
215217
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,19 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) {
16141614
if (T.isNull())
16151615
return true;
16161616

1617-
if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
1617+
bool DependentLambdaType = false;
1618+
QualType DesugaredType = T.getDesugaredType(SemaRef.getASTContext());
1619+
CXXRecordDecl *RD = DesugaredType->getAsCXXRecordDecl();
1620+
if (RD && RD->isLambda()) {
1621+
QualType LambdaCallType = RD->getLambdaCallOperator()->getType();
1622+
if (LambdaCallType->isInstantiationDependentType() ||
1623+
LambdaCallType->isVariablyModifiedType()) {
1624+
DependentLambdaType = true;
1625+
}
1626+
}
1627+
1628+
if (T->isInstantiationDependentType() || T->isVariablyModifiedType() ||
1629+
DependentLambdaType)
16181630
return false;
16191631

16201632
getSema().MarkDeclarationsReferencedInType(Loc, T);
@@ -2683,9 +2695,21 @@ QualType Sema::SubstType(QualType T,
26832695
"Cannot perform an instantiation without some context on the "
26842696
"instantiation stack");
26852697

2698+
bool DependentLambdaType = false;
2699+
QualType DesugaredType = T.getDesugaredType(getASTContext());
2700+
CXXRecordDecl *RD = DesugaredType->getAsCXXRecordDecl();
2701+
if (RD && RD->isLambda()) {
2702+
QualType LambdaCallType = RD->getLambdaCallOperator()->getType();
2703+
if (LambdaCallType->isInstantiationDependentType() ||
2704+
LambdaCallType->isVariablyModifiedType()) {
2705+
DependentLambdaType = true;
2706+
}
2707+
}
2708+
26862709
// If T is not a dependent type or a variably-modified type, there
26872710
// is nothing to do.
2688-
if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
2711+
if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType() &&
2712+
!DependentLambdaType)
26892713
return T;
26902714

26912715
TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);

clang/test/CodeGen/PR76674.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -std=c++20 -emit-llvm -o - %s
2+
// expected-no-diagnostics
3+
4+
template <class>
5+
struct A {
6+
template <class U>
7+
using Func = decltype([] {return U{};});
8+
};
9+
10+
A<int>::Func<int> f{};
11+
int i{f()};

0 commit comments

Comments
 (0)