[clang] [Clang] Skip past code generation for unevaluated lambdas (PR #124572)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 27 07:46:16 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)

<details>
<summary>Changes</summary>

This is taken from https://github.com/llvm/llvm-project/pull/122423#discussion_r1930102632 as suggested by Corentin.

Fixes #<!-- -->82926

---
Full diff: https://github.com/llvm/llvm-project/pull/124572.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+18-2) 
- (added) clang/test/CodeGenCXX/unevaluated-lambdas.cpp (+37) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f75c726e2751cf..7bb33d6b44d4ee 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 6a2331e59477a2..6a55dbd98b0b4d 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<CXXRecordDecl>(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 00000000000000..5bdf8294dc1fc3
--- /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<class Tp>
+using simd_vector = Tp;
+
+template<class VecT>
+using simd_vector_underlying_type_t
+    = decltype([]<class Tp>(simd_vector<Tp>) {}(VecT {}), 1);
+
+template<class VecT>
+void temp() {
+  // CHECK: call void @_ZZN7GH829264tempIcEEvvENKUliE_clEi
+  [](simd_vector_underlying_type_t<VecT>) {}(42);
+}
+
+void call() {
+  temp<simd_vector<char>>(); 
+}
+
+} // 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

``````````

</details>


https://github.com/llvm/llvm-project/pull/124572


More information about the cfe-commits mailing list