Index: clang/lib/CodeGen/CGObjCMac.cpp =================================================================== --- clang/lib/CodeGen/CGObjCMac.cpp +++ clang/lib/CodeGen/CGObjCMac.cpp @@ -6702,6 +6702,15 @@ IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); } + // NSObject is a fixed size. If we can see the @implementation of a class + // which inherits from NSObject then we know that all it's offsets also must + // be fixed, so we can set this as a constant global. + // FIXME: Can we do this if see a chain of super classes with implementations + // leading to NSObject? + if (ID->getImplementation() && ID->getSuperClass() && + ID->getSuperClass()->getName() == "NSObject") + IvarOffsetGV->setConstant(true); + if (CGM.getTriple().isOSBinFormatMachO()) IvarOffsetGV->setSection("__DATA, __objc_ivar"); return IvarOffsetGV; Index: clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | FileCheck %s --dump-input-on-failure + +@interface NSObject { + int these, will, never, change, ever; +} +@end + +@interface Sub : NSObject +@end + +@implementation Sub { + int sub_ivar; +} +@end + +// CHECK: @"OBJC_IVAR_$_Sub.sub_ivar" = hidden constant i64 20 + +@interface NotNSObject { + int these, might, change; +} +@end + +@interface Sub2 : NotNSObject +@end + +@implementation Sub2 { + int sub2_ivar; +} +@end + +// CHECK: @"OBJC_IVAR_$_Sub2.sub2_ivar" = hidden global i64 12 +