Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86_64] fix empty structure vaarg in c++ #77903

Closed
wants to merge 3 commits into from
Closed

Conversation

hstk30-hw
Copy link
Contributor

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

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:X86 clang:codegen labels Jan 12, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 12, 2024

@llvm/pr-subscribers-backend-x86
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-codegen

Author: None (hstk30-hw)

Changes

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


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+5)
  • (added) clang/test/CodeGen/X86/x86_64-vaarg.c (+15)
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index d053f41ab168f5..fde76ed6709cef 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);
+}

Copy link

github-actions bot commented Jan 12, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 4d467215f162b487381e17b8cb59283af75ca50e 6891699009f796ec1c09fad268aa8ef51a1ada36 -- clang/test/CodeGen/X86/x86_64-vaarg.c clang/lib/CodeGen/Targets/X86.cpp
View the diff from clang-format here.
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index c2c1128083..4f9e903b8f 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2991,7 +2991,7 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
   uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8;
 
   if (isEmptyRecord(CGF.getContext(), Ty, true)) {
-    SizeInBytes = 0;  
+    SizeInBytes = 0;
   }
 
   llvm::Value *Offset =

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.
CoTinker and others added 2 commits January 12, 2024 18:50
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.
@hstk30-hw hstk30-hw closed this Jan 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 clang:codegen clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants