[clang] [Clang][CodeGen] Fix weak array assignment cleanup IR (PR #235334)

Chakram Siri via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 24 10:52:00 PDT 2026


https://github.com/chakramsiri created https://github.com/llvm/llvm-project/pull/235334

Fixes [[#235144](https://github.com/llvm/llvm-project/issues/235144)]
The issue was that weak array assignment helpers generated invalid cleanup IR when assigning structs containing arrays of weak Objective-C references.

Added a cleanup scope around the per-element visitor call in `CGNonTrivialStruct.cpp` and added a regression test in `weak-array-assignment.m` to cover both copy assignment and assignment from a returned struct.

## Testing

- `llvm-lit -v clang/test/CodeGenObjC/weak-array-assignment.m` — **Passed**
- Related non-trivial struct tests — **6/6 passed**
- `llvm-lit clang/test/CodeGenObjC` — **359 passed, 18 unsupported, 0 failures**
- Verified that the generated IR contains the expected weak-reference load, store, and cleanup operations.

GenAI(Chatgpt) Assisted with understanding of the source code and in helping with edge case tests.

>From 37f933b814122e1341d8216174272d989f57747a Mon Sep 17 00:00:00 2001
From: Siri Chakram <cs24btech11017 at iith.ac.in>
Date: Sat, 24 Oct 2026 23:15:49 +0530
Subject: [PATCH] [Clang][CodeGen] Fix weak array assignment cleanup IR

---
 clang/lib/CodeGen/CGNonTrivialStruct.cpp      |  8 +++---
 .../test/CodeGenObjC/weak-array-assignment.m  | 26 +++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CodeGenObjC/weak-array-assignment.m

diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
index 0a383c8f919d95..6ce8f113eca624 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -414,9 +414,11 @@ template <class Derived> struct GenFuncBase {
                     StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
 
     EltQT = IsVolatile ? EltQT.withVolatile() : EltQT;
-    this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
-                                    NewAddrs);
-
+    {
+      CodeGenFunction::RunCleanupsScope Scope(CGF);
+      this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
+                                      NewAddrs);
+    }
     LoopBB = CGF.Builder.GetInsertBlock();
 
     for (unsigned I = 0; I < N; ++I) {
diff --git a/clang/test/CodeGenObjC/weak-array-assignment.m b/clang/test/CodeGenObjC/weak-array-assignment.m
new file mode 100644
index 00000000000000..7063f382234193
--- /dev/null
+++ b/clang/test/CodeGenObjC/weak-array-assignment.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks -fobjc-runtime=ios-11.0 -emit-llvm -o - %s | FileCheck %s
+
+typedef struct {
+  __weak id values[2];
+} WeakArray;
+
+WeakArray getWeakArray(void);
+
+// CHECK-LABEL: define void @copyWeakArray(
+// CHECK: call ptr @llvm.objc.loadWeakRetained
+// CHECK: call ptr @llvm.objc.storeWeak
+// CHECK: call void @llvm.objc.release
+
+void copyWeakArray(WeakArray *dst, WeakArray *src) {
+  *dst = *src;
+}
+
+// CHECK-LABEL: define void @moveWeakArray(
+// CHECK: call ptr @llvm.objc.loadWeakRetained
+// CHECK: call ptr @llvm.objc.storeWeak
+// CHECK: call void @llvm.objc.destroyWeak
+// CHECK: call void @llvm.objc.release
+
+void moveWeakArray(WeakArray *dst) {
+  *dst = getWeakArray();
+}



More information about the cfe-commits mailing list