[clang] [X86_64] Fix empty field error in vaarg of C++. (PR #101639)
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 8 12:33:27 PDT 2024
================
@@ -3124,26 +3124,40 @@ RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1));
RegAddr = Tmp.withElementType(LTy);
- } else if (neededInt) {
- RegAddr = Address(CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, gp_offset),
- LTy, CharUnits::fromQuantity(8));
-
+ } else if (neededInt || neededSSE == 1) {
// Copy to a temporary if necessary to ensure the appropriate alignment.
auto TInfo = getContext().getTypeInfoInChars(Ty);
uint64_t TySize = TInfo.Width.getQuantity();
CharUnits TyAlign = TInfo.Align;
+ llvm::Value *GpOrFpOffset = neededInt ? gp_offset : fp_offset;
+ uint64_t Alignment = neededInt ? 8 : 16;
+ if (auto Offset = AI.getDirectOffset()) {
+ Address Tmp = CGF.CreateMemTemp(Ty);
+ llvm::Type *TyHi = AI.getCoerceToType();
+ llvm::Value *Addr =
+ CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, GpOrFpOffset);
+ llvm::Value *Src = CGF.Builder.CreateAlignedLoad(TyHi, Addr, TyAlign);
+ llvm::Value *PtrOffset = llvm::ConstantInt::get(CGF.Int32Ty, Offset);
+ Address Dst = Address(
+ CGF.Builder.CreateGEP(CGF.Int8Ty, Tmp.getBasePointer(), PtrOffset),
+ LTy, TyAlign);
+ CGF.Builder.CreateStore(Src, Dst);
+ RegAddr = Tmp.withElementType(LTy);
+ } else {
+ RegAddr =
+ Address(CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, GpOrFpOffset),
+ LTy, CharUnits::fromQuantity(Alignment));
+ }
+
// Copy into a temporary if the type is more aligned than the
// register save area.
- if (TyAlign.getQuantity() > 8) {
+ if (neededInt && TyAlign.getQuantity() > 8) {
----------------
efriedma-quic wrote:
Can we refactor the code so it's clear we never create two temporaries for the same va_arg? Use an else-if instead of a separate if.
It looks it's possible that we end up reading past the end of the register save area for something like:
```
struct {
long long b;
struct{} a;
};
```
Can you also fix that while you're here? (Not sure that actually has any visible effect, but better to be on the safe side.)
https://github.com/llvm/llvm-project/pull/101639
More information about the cfe-commits
mailing list