Skip to content

Commit

Permalink
[CodeGen][ARM] Fix ARMABIInfo::EmitVAAarg crash with empty record typ…
Browse files Browse the repository at this point in the history
…e variadic arg

Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg

Open issue: llvm/llvm-project#58794

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D138137

(cherry picked from commit 80f4446)
  • Loading branch information
yronglin authored and tru committed Nov 29, 2022
1 parent abcd034 commit 088f336
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7047,10 +7047,10 @@ Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,

// Empty records are ignored for parameter passing purposes.
if (isEmptyRecord(getContext(), Ty, true)) {
Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
getVAListElementType(CGF), SlotSize);
Addr = CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
return Addr;
VAListAddr = CGF.Builder.CreateElementBitCast(VAListAddr, CGF.Int8PtrTy);
auto *Load = CGF.Builder.CreateLoad(VAListAddr);
Address Addr = Address(Load, CGF.Int8Ty, SlotSize);
return CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
}

CharUnits TySize = getContext().getTypeSizeInChars(Ty);
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CodeGen/arm-vaarg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %clang -Xclang -no-opaque-pointers -mfloat-abi=soft -target arm-linux-gnu -emit-llvm -S -o - %s | FileCheck %s

struct Empty {};

struct Empty emptyvar;

void take_args(int a, ...) {
// CHECK: [[ALLOCA_VA_LIST:%[a-zA-Z0-9._]+]] = alloca %struct.__va_list, align 4
// CHECK: call void @llvm.va_start
// CHECK-NEXT: [[AP_ADDR:%[a-zA-Z0-9._]+]] = bitcast %struct.__va_list* [[ALLOCA_VA_LIST]] to i8**
// CHECK-NEXT: [[LOAD_AP:%[a-zA-Z0-9._]+]] = load i8*, i8** [[AP_ADDR]], align 4
// CHECK-NEXT: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* [[LOAD_AP]] to %struct.Empty*

// It's conceivable that EMPTY_PTR may not actually be a valid pointer
// (e.g. it's at the very bottom of the stack and the next page is
// invalid). This doesn't matter provided it's never loaded (there's no
// well-defined way to tell), but it becomes a problem if we do try to use it.
// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]]
__builtin_va_list l;
__builtin_va_start(l, a);
emptyvar = __builtin_va_arg(l, struct Empty);
__builtin_va_end(l);
}

0 comments on commit 088f336

Please sign in to comment.