Skip to content

Commit f515e67

Browse files
committed
[Clang] Skip past code generation for unevaluated lambdas
As suggested by Corentin, this is taken from llvm#122423 (comment)
1 parent 13c6abf commit f515e67

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ Bug Fixes to C++ Support
966966
constraints are applied. (#GH122134)
967967
- Fixed canonicalization of pack indexing types - Clang did not always recognized identical pack indexing. (#GH123033)
968968
- Fixed a nested lambda substitution issue for constraint evaluation. (#GH123441)
969+
- Fixed some crashes involving unevaluated lambdas during code generation. (#GH82926)
969970

970971

971972
Bug Fixes to AST Handling

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5297,8 +5297,24 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
52975297
savedContext.pop();
52985298
}
52995299

5300-
DeclGroupRef DG(Function);
5301-
Consumer.HandleTopLevelDecl(DG);
5300+
// We never need to emit the code for a lambda in unevaluated context.
5301+
// We also can't mangle a lambda in the require clause of a function template
5302+
// during constraint checking as the MSI ABI would need to mangle the (not yet
5303+
// specialized) enclosing declaration
5304+
// FIXME: Should we try to skip this for non-lambda functions too?
5305+
bool ShouldSkipCG = [&] {
5306+
auto *RD = dyn_cast<CXXRecordDecl>(Function->getParent());
5307+
if (!RD || !RD->isLambda())
5308+
return false;
5309+
5310+
return llvm::any_of(ExprEvalContexts, [](auto &Context) {
5311+
return Context.isUnevaluated() || Context.isImmediateFunctionContext();
5312+
});
5313+
}();
5314+
if (!ShouldSkipCG) {
5315+
DeclGroupRef DG(Function);
5316+
Consumer.HandleTopLevelDecl(DG);
5317+
}
53025318

53035319
// This class may have local implicit instantiations that need to be
53045320
// instantiation within this scope.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 -std=c++2b -emit-llvm %s -o - | FileCheck %s -dump-input=always
2+
3+
namespace GH82926 {
4+
5+
template<class Tp>
6+
using simd_vector = Tp;
7+
8+
template<class VecT>
9+
using simd_vector_underlying_type_t
10+
= decltype([]<class Tp>(simd_vector<Tp>) {}(VecT {}), 1);
11+
12+
template<class VecT>
13+
void temp() {
14+
// CHECK: call void @_ZZN7GH829264tempIcEEvvENKUliE_clEi
15+
[](simd_vector_underlying_type_t<VecT>) {}(42);
16+
}
17+
18+
void call() {
19+
temp<simd_vector<char>>();
20+
}
21+
22+
} // namespace GH82926
23+
24+
namespace GH111058 {
25+
26+
// FIXME: This still crashes because the unevaluated lambda as an argument
27+
// is also supposed to skipping codegen in Sema::InstantiateFunctionDefinition().
28+
// auto eat(auto) {}
29+
30+
void foo() {
31+
// [] -> decltype(eat([] {})) {};
32+
33+
// CHECK: call void @"_ZZN8GH1110583fooEvENK3$_0clEv"
34+
[] -> decltype([](auto){}(1)) {}();
35+
}
36+
37+
} // namespace GH111058

0 commit comments

Comments
 (0)