diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f75c726e2751c..7bb33d6b44d4e 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -966,6 +966,7 @@ Bug Fixes to C++ Support constraints are applied. (#GH122134) - Fixed canonicalization of pack indexing types - Clang did not always recognized identical pack indexing. (#GH123033) - Fixed a nested lambda substitution issue for constraint evaluation. (#GH123441) +- Fixed some crashes involving unevaluated lambdas during code generation. (#GH82926) Bug Fixes to AST Handling diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6a2331e59477a..6a55dbd98b0b4 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5297,8 +5297,24 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, savedContext.pop(); } - DeclGroupRef DG(Function); - Consumer.HandleTopLevelDecl(DG); + // We never need to emit the code for a lambda in unevaluated context. + // We also can't mangle a lambda in the require clause of a function template + // during constraint checking as the MSI ABI would need to mangle the (not yet + // specialized) enclosing declaration + // FIXME: Should we try to skip this for non-lambda functions too? + bool ShouldSkipCG = [&] { + auto *RD = dyn_cast(Function->getParent()); + if (!RD || !RD->isLambda()) + return false; + + return llvm::any_of(ExprEvalContexts, [](auto &Context) { + return Context.isUnevaluated() || Context.isImmediateFunctionContext(); + }); + }(); + if (!ShouldSkipCG) { + DeclGroupRef DG(Function); + Consumer.HandleTopLevelDecl(DG); + } // This class may have local implicit instantiations that need to be // instantiation within this scope. diff --git a/clang/test/CodeGenCXX/unevaluated-lambdas.cpp b/clang/test/CodeGenCXX/unevaluated-lambdas.cpp new file mode 100644 index 0000000000000..5bdf8294dc1fc --- /dev/null +++ b/clang/test/CodeGenCXX/unevaluated-lambdas.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -std=c++2b -emit-llvm %s -o - | FileCheck %s -dump-input=always + +namespace GH82926 { + +template +using simd_vector = Tp; + +template +using simd_vector_underlying_type_t + = decltype([](simd_vector) {}(VecT {}), 1); + +template +void temp() { + // CHECK: call void @_ZZN7GH829264tempIcEEvvENKUliE_clEi + [](simd_vector_underlying_type_t) {}(42); +} + +void call() { + temp>(); +} + +} // namespace GH82926 + +namespace GH111058 { + +// FIXME: This still crashes because the unevaluated lambda as an argument +// is also supposed to skipping codegen in Sema::InstantiateFunctionDefinition(). +// auto eat(auto) {} + +void foo() { + // [] -> decltype(eat([] {})) {}; + + // CHECK: call void @"_ZZN8GH1110583fooEvENK3$_0clEv" + [] -> decltype([](auto){}(1)) {}(); +} + +} // namespace GH111058