================
@@ -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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits