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

Xavier Roche via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 6 00:51:37 PDT 2026


================
@@ -5232,6 +5232,26 @@ void CodeGenFunction::EmitWritebacks(const CallArgList &args) {
     emitWriteback(*this, I);
 }
 
+/// Whether emitting this glvalue neither has side effects nor reads mutable
+/// state, so deferring its byte read to the call boundary is equivalent to
+/// initializing the argument last, a sequencing C++17 [expr.call]/8 allows.
----------------
xroche wrote:

Hummm, you're right, and it is wider than your example. At runtime `<<`, `>>`, `&&`, `||`, `,` and `->*` all give wrong values, and assignment operators fail the other way round, since there the right operand is read first. Skipping the copy is not the cause: a local or member source still gets a real copy, just too late.

I never looked one frame up. `EmitCallArgs` already gets an `EvaluationOrder` computed from your list. The fix passes it into `EmitCallArg` and declines to forward when the order is fixed. That switch has no `operator[]`/`operator()` case though, so a C++23 explicit-object `operator[]` looks unordered while [expr.sub]/1 orders it. I flag any overloaded operator rather than add the two cases, which would also change MS ABI evaluation order.

Testing also found a crash: a class with both a copy constructor and a copy assignment operator hits the `EmitAggregateCopy` assert. The test type here declares only a copy constructor, which hid it. Relocation is now limited to byte-copyable types, `trivial_abi` included.

Would you prefer I fix the switch and depend on that? Should the crash fix be a separate commit?


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


More information about the cfe-commits mailing list