[clang] [Clang] Forward incoming Indirect parameters across musttail calls (PR #199351)

Xavier Roche via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 28 02:26:19 PDT 2026


================
@@ -5255,6 +5255,33 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
     }
   }
 
+  // Under musttail, hand a trivially-copyable record source's LValue to
+  // EmitCall rather than materializing an agg.tmp. EmitCall's Indirect path
+  // routes it via the matching incoming parameter, which survives the tail
+  // call. Limited to params and locals: globals and captures don't have the
+  // dangle issue and the existing path may be more efficient for them.
+  if (HasAggregateEvalKind && MustTailCall && type->isRecordType() &&
----------------
xroche wrote:

Nope, it isn't musttail-specific.

The C path right above (the `CK_LValueToRValue` case) already forwards unconditionally, so the `MustTailCall` gate was the only thing keeping the C++ trivial copy/move case from doing the same. Dropped the gate and the storage restriction: a trivial copy/move ctor whose source is a variable now forwards the source LValue for any call, and `EmitCall` makes the real copy at the byval/Indirect boundary. The source is kept to a direct variable reference for now; broader lvalues (`*p`, member access) stay on the existing path and can follow up.

Forwarding skips the copy, so it has to exclude the types whose by-value copy is not a plain memcpy in `EmitAggregateCopy`, or the special copy gets dropped. Excluded: a stripped derived-to-base cast (same-type guard, would slice), `hlsl_constant` sources (as the C path does), CUDA `device_builtin_surface`/`texture` types (lowered to a handle), and, under ObjC GC, records with an object member (need the `objc_memmove_collectable` write barrier). ARC/`__ptrauth`/PFP/inalloca are already excluded because they are not trivially copyable.


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


More information about the cfe-commits mailing list