Skip to content

Commit 2f42907

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.
1 parent 4d46721 commit 2f42907

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

clang/lib/CodeGen/Targets/X86.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2988,7 +2988,10 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
29882988
// AMD64-ABI 3.5.7p5: Step 10. Align l->overflow_arg_area upwards to
29892989
// an 8 byte boundary.
29902990

2991-
uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
2991+
uint64_t SizeInBytes = 0;
2992+
if (!isEmptyRecord(CGF.getContext(), Ty, true, true))
2993+
SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
2994+
29922995
llvm::Value *Offset =
29932996
llvm::ConstantInt::get(CGF.Int32Ty, (SizeInBytes + 7) & ~7);
29942997
overflow_arg_area = CGF.Builder.CreateGEP(CGF.Int8Ty, overflow_arg_area,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4
2+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
3+
4+
struct Empty { struct { struct { } e; }; };
5+
6+
struct Empty emptyvar;
7+
8+
void take_args(int a, ...) {
9+
// CHECK: %overflow_arg_area = load ptr, ptr %overflow_arg_area_p, align 8
10+
// CHECK-NEXT: %overflow_arg_area.next = getelementptr i8, ptr %overflow_arg_area, i32 0
11+
// CHECK-NEXT: store ptr %overflow_arg_area.next, ptr %overflow_arg_area_p, align 8
12+
__builtin_va_list l;
13+
__builtin_va_start(l, a);
14+
emptyvar = __builtin_va_arg(l, struct Empty);
15+
__builtin_va_end(l);
16+
}

0 commit comments

Comments
 (0)