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

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 15 04:41:55 PDT 2024


https://github.com/hstk30-hw updated https://github.com/llvm/llvm-project/pull/77907

>From 75eb445f153d2391a8980716f36be77ed2fb24ed Mon Sep 17 00:00:00 2001
From: Longsheng Mou <moulongsheng at huawei.com>
Date: Fri, 12 Jan 2024 18:24:08 +0800
Subject: [PATCH] [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.
---
 clang/lib/CodeGen/Targets/X86.cpp      |  5 +++++
 clang/test/CodeGenCXX/x86_64-vaarg.cpp | 12 ++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 clang/test/CodeGenCXX/x86_64-vaarg.cpp

diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index d053f41ab168f5..c5c66bb425628a 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -3014,6 +3014,11 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
   ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE,
                                        /*isNamedArg*/false);
 
+  // Empty records are ignored for parameter passing purposes.
+  if (AI.isIgnore()) {
+    return CGF.CreateMemTemp(Ty);
+  }
+
   // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
   // in the registers. If not go to step 7.
   if (!neededInt && !neededSSE)
diff --git a/clang/test/CodeGenCXX/x86_64-vaarg.cpp b/clang/test/CodeGenCXX/x86_64-vaarg.cpp
new file mode 100644
index 00000000000000..4d77a5c89455cd
--- /dev/null
+++ b/clang/test/CodeGenCXX/x86_64-vaarg.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+typedef struct { struct {} a; } empty;
+
+// CHECK-LABEL: define{{.*}} void @_Z17empty_record_testv()
+empty empty_record_test(void) {
+// CHECK: [[RET:%[a-z]+]] = alloca %struct.empty, align 1
+// CHECK: [[TMP:%[a-z]+]] = alloca %struct.empty, align 1
+// CHECK: call void @llvm.memcpy{{.*}}(ptr align 1 [[RET]], ptr align 1 [[TMP]]
+  __builtin_va_list list;
+  return __builtin_va_arg(list, empty);
+}



More information about the cfe-commits mailing list