Skip to content

Commit 95e4455

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 95e4455

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

clang/lib/CodeGen/Targets/X86.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,10 @@ 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+
30173021
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
30183022
// in the registers. If not go to step 7.
30193023
if (!neededInt && !neededSSE)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -x c -o - %s | FileCheck %s
3+
4+
typedef struct { struct {} a; } empty;
5+
6+
// CHECK-LABEL: define{{.*}} void @{{.*}}empty_record_test{{.*}}()
7+
empty empty_record_test(void) {
8+
// CHECK: [[RET:%[a-z]+]] = alloca %struct.empty, align 1
9+
// CHECK: [[TMP:%[a-z]+]] = alloca %struct.empty, align 1
10+
// CHECK: call void @llvm.memcpy{{.*}}(ptr align 1 [[RET]], ptr align 1 [[TMP]]
11+
__builtin_va_list list;
12+
return __builtin_va_arg(list, empty);
13+
}

0 commit comments

Comments
 (0)