https://github.com/rjodinchr updated 
https://github.com/llvm/llvm-project/pull/238332

>From 3536fe4c60fa3cfd1c2726bdaa9e2669dd9f18c0 Mon Sep 17 00:00:00 2001
From: Romaric Jodin <[email protected]>
Date: Tue, 3 Nov 2026 11:53:09 +0100
Subject: [PATCH] [CodeGen] Store Value* instead of polymorphic Cleanup in
 EmitCall

In CodeGenFunction::EmitCall, CallLifetimeEnd derives from the
polymorphic base class EHScopeStack::Cleanup so that it can be pushed
onto EHStack when cleanup happens on both normal and unwind edges. For
non-cleanup calls, however, CallLifetimeEnd instances were also stored
by value in SmallVector<CallLifetimeEnd, 2> CallLifetimeEndAfterCall and
invoked directly after the call.

SmallVector inline storage uses aligned_char_array_union raw bytes and
obtains a typed begin() pointer via reinterpret_cast<T *>(Buffer) before
elements are constructed in place. Because CallLifetimeEnd has a vtable,
compiling with Control Flow Integrity (-fsanitize=cfi-unrelated-cast)
instruments the cast inside SmallVector::begin() and checks the vtable
pointer on uninitialized stack bytes during push_back(), trapping at
runtime before placement new can construct the CallLifetimeEnd object.

Since CallLifetimeEnd only wraps a single llvm::Value *Addr and calls
CGF.EmitLifetimeEnd(Addr), store llvm::Value * directly in
SmallVector<llvm::Value *, 2> CallLifetimeEndAfterCall and invoke
EmitLifetimeEnd on each address after the call.
---
 clang/lib/CodeGen/CGCall.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 718ee7b547b43d..1d7f9f742b87e9 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -5821,7 +5821,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
   // When passing arguments using temporary allocas, we need to add the
   // appropriate lifetime markers. This vector keeps track of all the lifetime
   // markers that need to be ended right after the call.
-  SmallVector<CallLifetimeEnd, 2> CallLifetimeEndAfterCall;
+  SmallVector<llvm::Value *, 2> CallLifetimeEndAfterCall;
 
   // Translate all of the arguments as necessary to match the IR lowering.
   assert(CallInfo.arg_size() == CallArgs.size() &&
@@ -5976,7 +5976,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
       // Emit lifetime markers for the temporary alloca and add cleanup code to
       // emit the end lifetime marker after the call.
       if (EmitLifetimeStart(AI.getPointer()))
-        CallLifetimeEndAfterCall.emplace_back(AI);
+        CallLifetimeEndAfterCall.push_back(AI.getPointer());
 
       // Generate the copy.
       I->copyInto(*this, AI);
@@ -6858,10 +6858,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo 
&CallInfo,
     AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
   }
 
-  // Explicitly call CallLifetimeEnd::Emit just to re-use the code even though
-  // we can't use the full cleanup mechanism.
-  for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
-    LifetimeEnd.Emit(*this, /*Flags=*/{});
+  // Emit the end lifetime markers for any temporary allocas created for the
+  // call arguments.
+  for (llvm::Value *LifetimeEndAddr : CallLifetimeEndAfterCall)
+    EmitLifetimeEnd(LifetimeEndAddr);
 
   if (!ReturnValue.isExternallyDestructed() &&
       RetTy.isDestructedType() == QualType::DK_nontrivial_c_struct)

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to