[clang] [X86_64] fix empty structure vaarg in c++ (PR #77907)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 12 03:07:02 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: None (hstk30-hw)

<details>
<summary>Changes</summary>

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. fix #<!-- -->77036

---
Full diff: https://github.com/llvm/llvm-project/pull/77907.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/X86.cpp (+5) 
- (added) clang/test/CodeGen/X86/x86_64-vaarg.c (+15) 


``````````diff
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index d053f41ab168f5..c2c11280838b12 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2989,6 +2989,11 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
   // an 8 byte boundary.
 
   uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
+
+  if (isEmptyRecord(CGF.getContext(), Ty, true)) {
+    SizeInBytes = 0;  
+  }
+
   llvm::Value *Offset =
       llvm::ConstantInt::get(CGF.Int32Ty, (SizeInBytes + 7)  & ~7);
   overflow_arg_area = CGF.Builder.CreateGEP(CGF.Int8Ty, overflow_arg_area,
diff --git a/clang/test/CodeGen/X86/x86_64-vaarg.c b/clang/test/CodeGen/X86/x86_64-vaarg.c
new file mode 100644
index 00000000000000..ae201a2d3f3017
--- /dev/null
+++ b/clang/test/CodeGen/X86/x86_64-vaarg.c
@@ -0,0 +1,15 @@
+// RUN: %clang -xc++ -target x86_64-linux-gnu -emit-llvm -S -o - %s | FileCheck %s
+
+struct Empty {};
+
+struct Empty emptyvar;
+
+void take_args(int a, ...) {
+    // CHECK:      %overflow_arg_area = load ptr, ptr %overflow_arg_area_p, align 8
+    // CHECK-NEXT: %overflow_arg_area.next = getelementptr i8, ptr %overflow_arg_area, i32 0
+    // CHECK-NEXT: store ptr %overflow_arg_area.next, ptr %overflow_arg_area_p, align 8
+    __builtin_va_list l;
+    __builtin_va_start(l, a);
+    emptyvar = __builtin_va_arg(l, struct Empty);
+    __builtin_va_end(l);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/77907


More information about the cfe-commits mailing list