Skip to content

Commit aa02306

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 aa02306

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

clang/lib/CodeGen/Targets/X86.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,16 @@ 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+
CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty);
3020+
VAListAddr = CGF.Builder.CreateStructGEP(VAListAddr, 2);
3021+
llvm::Value *Load = CGF.Builder.CreateLoad(VAListAddr);
3022+
llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, 0);
3023+
Load = CGF.Builder.CreateGEP(CGF.Int8Ty, Load, Offset);
3024+
return Address(Load, CGF.ConvertTypeForMem(Ty), Align);
3025+
}
3026+
30173027
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
30183028
// in the registers. If not go to step 7.
30193029
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: [[ADDR0:%[a-z._0-9]+]] = getelementptr inbounds %struct.__va_list_tag, ptr %arraydecay, i32 0, i32 2
8+
// CHECK-NEXT: [[ADDR1:%[a-z._0-9]+]] = load ptr, ptr [[ADDR0]], align 8
9+
// CHECK-NEXT: [[ADDR2:%[a-z._0-9]+]] = getelementptr i8, ptr [[ADDR1]], i32 0
10+
__builtin_va_list list;
11+
return __builtin_va_arg(list, empty);
12+
}

0 commit comments

Comments
 (0)