Function &F;
MemorySanitizer &MS;
MemorySanitizerVisitor &MSV;
+ bool IsSoftFloatABI;
Value *VAArgTLSCopy = nullptr;
Value *VAArgTLSOriginCopy = nullptr;
Value *VAArgOverflowSize = nullptr;
VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
MemorySanitizerVisitor &MSV)
- : F(F), MS(MS), MSV(MSV) {}
+ : F(F), MS(MS), MSV(MSV),
+ IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
- ArgKind classifyArgument(Type *T, bool IsSoftFloatABI) {
+ ArgKind classifyArgument(Type *T) {
// T is a SystemZABIInfo::classifyArgumentType() output, and there are
// only a few possibilities of what it can be. In particular, enums, single
// element structs and large types have already been taken care of.
}
void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
- bool IsSoftFloatABI = CB.getCalledFunction()
- ->getFnAttribute("use-soft-float")
- .getValueAsBool();
unsigned GpOffset = SystemZGpOffset;
unsigned FpOffset = SystemZFpOffset;
unsigned VrIndex = 0;
// SystemZABIInfo does not produce ByVal parameters.
assert(!CB.paramHasAttr(ArgNo, Attribute::ByVal));
Type *T = A->getType();
- ArgKind AK = classifyArgument(T, IsSoftFloatABI);
+ ArgKind AK = classifyArgument(T);
if (AK == ArgKind::Indirect) {
T = PointerType::get(T, 0);
AK = ArgKind::GeneralPurpose;
; CHECK: declare void @__msan_maybe_store_origin_4(i32 zeroext, ptr, i32 zeroext)
; CHECK: declare void @__msan_maybe_warning_8(i64 zeroext, i32 zeroext)
; CHECK: declare void @__msan_maybe_store_origin_8(i64 zeroext, ptr, i32 zeroext)
+
+; Test vararg function pointers.
+;
+; void (*ptr)(int, ...);
+; void call_ptr(void) { ptr(0); }
+
+@ptr = dso_local global ptr null, align 8
+
+define dso_local void @call_ptr() {
+ %1 = load ptr, ptr @ptr, align 8
+ call void (i32, ...) %1(i32 noundef signext 0)
+ ret void
+}