[clang] [X86] Fix CodeGen crash for arrays of empty structs and unions (PR #224203)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 19 20:13:05 PDT 2026
https://github.com/hstk30-hw updated https://github.com/llvm/llvm-project/pull/224203
>From 9ffb2ac56314178f24d92a31e79feb05e03886ad Mon Sep 17 00:00:00 2001
From: MaoJian <maojian16 at huawei.com>
Date: Thu, 17 Sep 2026 14:39:39 +0800
Subject: [PATCH] [X86] Fix CodeGen crash for arrays of empty structs and
unions
getFPTypeAtOffset() divides by the allocation size of an array
element when normalizing IROffset. Empty structs and unions have
zero allocation size, so arrays of these types can cause a
division-by-zero during X86 ABI lowering.
Return nullptr for zero-sized array elements and add CodeGen tests
for empty struct and union arrays.
---
clang/lib/CodeGen/Targets/X86.cpp | 2 ++
.../CodeGen/X86/empty-struct-union-array.c | 29 +++++++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 clang/test/CodeGen/X86/empty-struct-union-array.c
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 14fe5ffae8372..21f9929cfa882 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2528,6 +2528,8 @@ static llvm::Type *getFPTypeAtOffset(llvm::Type *IRType, unsigned IROffset,
if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {
llvm::Type *EltTy = ATy->getElementType();
unsigned EltSize = TD.getTypeAllocSize(EltTy);
+ if (EltSize == 0)
+ return nullptr;
IROffset -= IROffset / EltSize * EltSize;
return getFPTypeAtOffset(EltTy, IROffset, TD);
}
diff --git a/clang/test/CodeGen/X86/empty-struct-union-array.c b/clang/test/CodeGen/X86/empty-struct-union-array.c
new file mode 100644
index 0000000000000..476e383c76e42
--- /dev/null
+++ b/clang/test/CodeGen/X86/empty-struct-union-array.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple=x86_64 -emit-llvm -o - %s | FileCheck %s
+
+struct StructArray {
+ long a;
+ float b;
+ struct {
+ } c[7];
+};
+
+struct UnionArray {
+ long a;
+ float b;
+ union {
+ } c[7];
+};
+
+// CHECK-LABEL: define{{.*}} @foo_struct
+// CHECK: ret
+struct StructArray foo_struct() {
+ struct StructArray s;
+ return s;
+}
+
+// CHECK-LABEL: define{{.*}} @foo_union
+// CHECK: ret
+struct UnionArray foo_union() {
+ struct UnionArray s;
+ return s;
+}
More information about the cfe-commits
mailing list