[clang] fix: compatible C++ empty record with align UB with gcc (PR #72197)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 20 17:47:18 PST 2023
https://github.com/hstk30-hw updated https://github.com/llvm/llvm-project/pull/72197
>From 9a00824d0ac164d94c9cabfb4544eb6ef2e81802 Mon Sep 17 00:00:00 2001
From: hstk30-hw <hanwei62 at huawei.com>
Date: Sat, 18 Nov 2023 11:00:29 +0000
Subject: [PATCH] fix: empty record size > 64 with align let va_list get out of
sync
---
clang/lib/CodeGen/Targets/AArch64.cpp | 7 ++++++-
clang/test/CodeGen/aarch64-args.cpp | 19 +++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index be5145daa00b7f5..b6457cff7d6583e 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -307,7 +307,12 @@ AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadic,
// 0.
if (IsEmpty && Size == 0)
return ABIArgInfo::getIgnore();
- return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
+ // An empty struct can have size greater than one byte if alignment is
+ // involved.
+ // When size <= 64, we still hold it by i8 in IR and lowering to registers.
+ // When Size > 64, just fall through to avoid va_list out of sync.
+ if (Size <= 64)
+ return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
}
// Homogeneous Floating-point Aggregates (HFAs) need to be expanded.
diff --git a/clang/test/CodeGen/aarch64-args.cpp b/clang/test/CodeGen/aarch64-args.cpp
index fe1298cc683a404..1fc1b89785fee81 100644
--- a/clang/test/CodeGen/aarch64-args.cpp
+++ b/clang/test/CodeGen/aarch64-args.cpp
@@ -65,3 +65,22 @@ EXTERNC struct SortOfEmpty sort_of_empty_ret(void) {
struct SortOfEmpty e;
return e;
}
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align8_arg(i8 %a.coerce, i32 noundef %b)
+struct EmptyAlign8 { int __attribute__((aligned(8))) : 0; };
+EXTERNC int empty_align8_arg(struct EmptyAlign8 a, int b) {
+ return b;
+}
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align16_arg(i128 %a.coerce, i32 noundef %b)
+struct EmptyAlign16 { long long int __attribute__((aligned(16))) : 0; };
+EXTERNC int empty_align16_arg(struct EmptyAlign16 a, int b) {
+ return b;
+}
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align32_arg(ptr noundef %a, i32 noundef %b)
+struct EmptyAlign32 { long long int __attribute__((aligned(32))) : 0; };
+EXTERNC int empty_align32_arg(struct EmptyAlign32 a, int b) {
+ return b;
+}
+
More information about the cfe-commits
mailing list