================ @@ -1328,15 +1328,15 @@ void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) { Address ArgValue = Address::invalid(); - Address ArgPtr = CGF.EmitVAArg(VE, ArgValue); + RValue ArgPtr = CGF.EmitVAArg(VE, ArgValue); // If EmitVAArg fails, emit an error. - if (!ArgPtr.isValid()) { + if (!ArgValue.isValid()) { CGF.ErrorUnsupported(VE, "aggregate va_arg expression"); return; } - EmitFinalDestCopy(VE->getType(), CGF.MakeAddrLValue(ArgPtr, VE->getType())); + EmitFinalDestCopy(VE->getType(), ArgPtr); ---------------- rjmccall wrote:
CodeGen handles aggregates by keeping them in memory. Everything to do with aggregate expression emission generally works by passing around a destination address that the value should be placed in — you evaluate the expression into that address, then just put that address into the `RValue` you return. If you don't pass an address down, generally operations have to evaluate into a temporary, which can create redundant `memcpy`s. In `AggExprEmitter`, the destination address is the `Dest` member. We may just be doing an assignment into `Dest` and not an initialization, though, which has important semantic differences in some cases and is (confusingly, sorry) tracked with `.isPotentiallyAliased()`. The easiest way to handle that is to make sure the final copy is done with `EmitFinalDestCopy`. You'll need to add a method like this to `CodeGenFunction`: ```c++ void EmitAggFinalDestCopy(QualType type, AggValueSlot dest, const LValue &src, ExprValueKind srcKind); ``` which makes an `AggExprEmitter` and calls `EmitFinalDestCopy` on it. https://github.com/llvm/llvm-project/pull/94635 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits