[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