Skip to content

Commit d778404

Browse files
committed
[ObjC] Expand isClassLayoutKnownStatically to base classes as long as the implementation of it is known
Only NSObject we can trust the layout of won't change even though we cannot directly see its @implementation
1 parent 84b5178 commit d778404

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

clang/lib/CodeGen/CGObjCMac.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,11 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
15951595
bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
15961596
// Test a class by checking its superclasses up to
15971597
// its base class if it has one.
1598+
1599+
// Cannot check a null class
1600+
if (!ID)
1601+
return false;
1602+
15981603
for (; ID; ID = ID->getSuperClass()) {
15991604
// The layout of base class NSObject
16001605
// is guaranteed to be statically known
@@ -1606,7 +1611,9 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
16061611
if (!ID->getImplementation())
16071612
return false;
16081613
}
1609-
return false;
1614+
1615+
// We know the layout of all the intermediate classes and superclasses.
1616+
return true;
16101617
}
16111618

16121619
public:

clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden constant i64 48
99
// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = constant i64 56
1010
// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden constant i64 64
11+
12+
// CHECK: @"OBJC_IVAR_$_RootClass.these" = constant i64 0
13+
// CHECK: @"OBJC_IVAR_$_RootClass.dont" = constant i64 4
14+
// CHECK: @"OBJC_IVAR_$_RootClass.change" = constant i64 4
15+
// CHECK: @"OBJC_IVAR_$_StillStaticLayout.static_layout_ivar" = hidden global i32 12
16+
1117
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
1218

1319
@interface NSObject {
@@ -120,7 +126,29 @@ -(void)intermediateSubclassVar {
120126
// CHECK: getelementptr inbounds i8, ptr %1, i64 64
121127
@end
122128

123-
@interface NotNSObject {
129+
__attribute((objc_root_class)) @interface RootClass {
130+
int these, dont, change;
131+
}
132+
@end
133+
134+
@implementation RootClass
135+
@end
136+
137+
@interface StillStaticLayout : RootClass
138+
@end
139+
140+
@implementation StillStaticLayout {
141+
int static_layout_ivar;
142+
}
143+
144+
// CHECK-LABEL: define internal void @"\01-[StillStaticLayout meth]"
145+
-(void)meth {
146+
static_layout_ivar = 0;
147+
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$StillStaticLayout.static_layout_ivar
148+
}
149+
@end
150+
151+
__attribute((objc_root_class)) @interface NotNSObject {
124152
int these, might, change;
125153
}
126154
@end

0 commit comments

Comments
 (0)