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
