https://github.com/MaooJian created 
https://github.com/llvm/llvm-project/pull/224203

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.

>From a8eb9e1b89ae9a3c82a9b81957c14cd889ec8719 Mon Sep 17 00:00:00 2001
From: MaoJian <[email protected]>
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..37efe8dbfde4b
--- /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;
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to