Skip to content

Commit 75eb445

Browse files
CoTinkerhstk30-hw
authored andcommitted
[X86_64] fix empty structure vaarg in c++
SizeInBytes of empty structure is 0 in C, while 1 in C++. And empty structure argument of the function is ignored in X86_64 backend.As a result, the value of variable arguments in C++ is incorrect.So we should just make a temporary and return its address.
1 parent 4d46721 commit 75eb445

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

clang/lib/CodeGen/Targets/X86.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,11 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
30143014
ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE,
30153015
/*isNamedArg*/false);
30163016

3017+
// Empty records are ignored for parameter passing purposes.
3018+
if (AI.isIgnore()) {
3019+
return CGF.CreateMemTemp(Ty);
3020+
}
3021+
30173022
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
30183023
// in the registers. If not go to step 7.
30193024
if (!neededInt && !neededSSE)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
2+
3+
typedef struct { struct {} a; } empty;
4+
5+
// CHECK-LABEL: define{{.*}} void @_Z17empty_record_testv()
6+
empty empty_record_test(void) {
7+
// CHECK: [[RET:%[a-z]+]] = alloca %struct.empty, align 1
8+
// CHECK: [[TMP:%[a-z]+]] = alloca %struct.empty, align 1
9+
// CHECK: call void @llvm.memcpy{{.*}}(ptr align 1 [[RET]], ptr align 1 [[TMP]]
10+
__builtin_va_list list;
11+
return __builtin_va_arg(list, empty);
12+
}

0 commit comments

Comments
 (0)