https://github.com/HendrikHuebner updated 
https://github.com/llvm/llvm-project/pull/215753

From 540a009157ced331b7a06759118c2092b0860050 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]>
Date: Wed, 5 Aug 2026 22:54:33 +0200
Subject: [PATCH 1/3] [CodeGen][ObjC] Preserve signed relative ivar offsets

GNUstep non-fragile relative ivar offsets may be negative. Compute and 
materialize them as signed values instead of wrapping the subtraction through 
uint64_t.
---
 clang/lib/CodeGen/CGObjCGNU.cpp | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 32a1afe310629..24e7a2e8f7ebb 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -1885,8 +1885,9 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
         ivarBuilder.add(MakeConstantString(TypeStr));
         // int *offset;
         uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
-        uint64_t Offset = BaseOffset - superInstanceSize;
-        llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
+        int64_t Offset = static_cast<int64_t>(BaseOffset) - superInstanceSize;
+        llvm::Constant *OffsetValue =
+            llvm::ConstantInt::getSigned(IntTy, Offset);
         std::string OffsetName = GetIVarOffsetVariableName(classDecl, IVD);
         llvm::GlobalVariable *OffsetVar = 
TheModule.getGlobalVariable(OffsetName);
         if (OffsetVar)
@@ -3804,11 +3805,12 @@ void CGObjCGNU::GenerateClass(const 
ObjCImplementationDecl *OID) {
             Context.getTypeSize(IVD->getType())));
       // Get the offset
       uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
-      uint64_t Offset = BaseOffset;
+      int64_t Offset = static_cast<int64_t>(BaseOffset);
       if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
-        Offset = BaseOffset - superInstanceSize;
+        Offset = static_cast<int64_t>(BaseOffset) - superInstanceSize;
       }
-      llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
+      llvm::Constant *OffsetValue =
+          llvm::ConstantInt::getSigned(IntTy, Offset);
       // Create the direct offset value
       std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." +
           IVD->getNameAsString();

From 730fa33e0835960f20912599a9bb4513b9bccadc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?= <[email protected]>
Date: Wed, 12 Aug 2026 10:04:24 +0200
Subject: [PATCH 2/3] Add test

---
 clang/test/CodeGenObjC/gnustep2-ivar-offset.m | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/clang/test/CodeGenObjC/gnustep2-ivar-offset.m 
b/clang/test/CodeGenObjC/gnustep2-ivar-offset.m
index dd133ba04e307..c238edcf79380 100644
--- a/clang/test/CodeGenObjC/gnustep2-ivar-offset.m
+++ b/clang/test/CodeGenObjC/gnustep2-ivar-offset.m
@@ -28,3 +28,22 @@ @implementation ANObject @end
 // CHECK: @.objc_ivar_list = private global { i32, i64, [4 x { ptr, ptr, ptr, 
i32, i32 }] } { i32 4, i64 32,
 // Check that we emit 1 as the size of _Bool, not 0.
 // CHECK-SAME:  @__objc_ivar_offset_ANObject.boolIvar.B, i32 1, i32 4
+
+
+// The derived class reuses tail padding in the base class.
+// Its ivar is at offset 12, while the superclass instance size is 16, so the 
relative offset is -4.
+@interface Base {
+  long long a;
+  char b;
+}
+@end
+
+@interface Derived : Base {
+  int c;
+}
+@end
+
+@implementation Base @end
+@implementation Derived @end
+
+// CHECK: @__objc_ivar_offset_Derived.c.i = global i32 -4

From fb2b4d672ec11a31922d2e2f8ab3f0c3f256d4a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hendrik=20H=C3=BCbner?=
 <[email protected]>
Date: Wed, 12 Aug 2026 12:01:20 +0200
Subject: [PATCH 3/3] fmt

---
 clang/lib/CodeGen/CGObjCGNU.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index 24e7a2e8f7ebb..44b182ad487fb 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -3809,8 +3809,7 @@ void CGObjCGNU::GenerateClass(const 
ObjCImplementationDecl *OID) {
       if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
         Offset = static_cast<int64_t>(BaseOffset) - superInstanceSize;
       }
-      llvm::Constant *OffsetValue =
-          llvm::ConstantInt::getSigned(IntTy, Offset);
+      llvm::Constant *OffsetValue = llvm::ConstantInt::getSigned(IntTy, 
Offset);
       // Create the direct offset value
       std::string OffsetName = "__objc_ivar_offset_value_" + ClassName +"." +
           IVD->getNameAsString();

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

Reply via email to