Skip to content

Commit 80f4446

Browse files
yronglinint6
authored andcommitted
[CodeGen][ARM] Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg
Fix ARMABIInfo::EmitVAAarg crash with empty record type variadic arg Open issue: llvm#58794 Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D138137
1 parent ac38a7d commit 80f4446

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7050,10 +7050,10 @@ Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
70507050

70517051
// Empty records are ignored for parameter passing purposes.
70527052
if (isEmptyRecord(getContext(), Ty, true)) {
7053-
Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
7054-
getVAListElementType(CGF), SlotSize);
7055-
Addr = CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
7056-
return Addr;
7053+
VAListAddr = CGF.Builder.CreateElementBitCast(VAListAddr, CGF.Int8PtrTy);
7054+
auto *Load = CGF.Builder.CreateLoad(VAListAddr);
7055+
Address Addr = Address(Load, CGF.Int8Ty, SlotSize);
7056+
return CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
70577057
}
70587058

70597059
CharUnits TySize = getContext().getTypeSizeInChars(Ty);

clang/test/CodeGen/arm-vaarg.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang -Xclang -no-opaque-pointers -mfloat-abi=soft -target arm-linux-gnu -emit-llvm -S -o - %s | FileCheck %s
2+
3+
struct Empty {};
4+
5+
struct Empty emptyvar;
6+
7+
void take_args(int a, ...) {
8+
// CHECK: [[ALLOCA_VA_LIST:%[a-zA-Z0-9._]+]] = alloca %struct.__va_list, align 4
9+
// CHECK: call void @llvm.va_start
10+
// CHECK-NEXT: [[AP_ADDR:%[a-zA-Z0-9._]+]] = bitcast %struct.__va_list* [[ALLOCA_VA_LIST]] to i8**
11+
// CHECK-NEXT: [[LOAD_AP:%[a-zA-Z0-9._]+]] = load i8*, i8** [[AP_ADDR]], align 4
12+
// CHECK-NEXT: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* [[LOAD_AP]] to %struct.Empty*
13+
14+
// It's conceivable that EMPTY_PTR may not actually be a valid pointer
15+
// (e.g. it's at the very bottom of the stack and the next page is
16+
// invalid). This doesn't matter provided it's never loaded (there's no
17+
// well-defined way to tell), but it becomes a problem if we do try to use it.
18+
// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]]
19+
__builtin_va_list l;
20+
__builtin_va_start(l, a);
21+
emptyvar = __builtin_va_arg(l, struct Empty);
22+
__builtin_va_end(l);
23+
}

0 commit comments

Comments
 (0)