[llvm-branch-commits] [clang] release/18.x: [ObjC] Check entire chain of superclasses to determine class layout (PR #84093)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Mar 5 15:38:27 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: AtariDreams (AtariDreams)
<details>
<summary>Changes</summary>
Backport of https://github.com/llvm/llvm-project/commit/923ddf65f4e21ec67018cf56e823895de18d83bc
---
Full diff: https://github.com/llvm/llvm-project/pull/84093.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGObjCMac.cpp (+14-6)
- (modified) clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m (+102)
``````````diff
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 517f7cddebc1a2..be628a909d89be 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1593,12 +1593,20 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
}
bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
- // 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. FIXME: Can we do this if see a chain of super classes with
- // implementations leading to NSObject?
- return ID->getImplementation() && ID->getSuperClass() &&
- ID->getSuperClass()->getName() == "NSObject";
+ // Test a class by checking its superclasses up to
+ // its base class if it has one.
+ for (; ID; ID = ID->getSuperClass()) {
+ // The layout of base class NSObject
+ // is guaranteed to be statically known
+ if (ID->getIdentifier()->getName() == "NSObject")
+ return true;
+
+ // If we cannot see the @implementation of a class,
+ // we cannot statically know the class layout.
+ if (!ID->getImplementation())
+ return false;
+ }
+ return false;
}
public:
diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 788b3220af3067..8d55e6c7d23081 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -1,6 +1,13 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | FileCheck %s
// CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass.superClassIvar" = hidden constant i64 20
+// CHECK: @"OBJC_IVAR_$_SuperClass._superClassProperty" = hidden constant i64 24
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar" = constant i64 32
+// CHECK: @"OBJC_IVAR_$_IntermediateClass.intermediateClassIvar2" = constant i64 40
+// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden constant i64 48
+// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = constant i64 56
+// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden constant i64 64
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
@interface NSObject {
@@ -14,12 +21,105 @@ @interface StaticLayout : NSObject
@implementation StaticLayout {
int static_layout_ivar;
}
+
+// CHECK-LABEL: define internal void @"\01-[StaticLayout meth]"
-(void)meth {
static_layout_ivar = 0;
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_StaticLayout
+ // CHECK: getelementptr inbounds i8, ptr %0, i64 20
+}
+ at end
+
+ at interface SuperClass : NSObject
+ at property (nonatomic, assign) int superClassProperty;
+ at end
+
+ at implementation SuperClass {
+ int superClassIvar; // Declare an ivar
+}
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass superClassMethod]"
+- (void)superClassMethod {
+ _superClassProperty = 42;
+ superClassIvar = 10;
+ // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SuperClass
+ // CHECK: getelementptr inbounds i8, ptr %1, i64 20
+}
+
+// Implicitly synthesized method here
+// CHECK-LABEL: define internal i32 @"\01-[SuperClass superClassProperty]"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 24
+
+// CHECK-LABEL: define internal void @"\01-[SuperClass setSuperClassProperty:]"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 24
+ at end
+
+ at interface IntermediateClass : SuperClass {
+ double intermediateClassIvar;
+
+ @protected
+ int intermediateClassIvar2;
+}
+ at property (nonatomic, strong) SuperClass *intermediateProperty;
+ at end
+
+ at implementation IntermediateClass
+ at synthesize intermediateProperty = _intermediateProperty;
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassMethod]"
+- (void)intermediateClassMethod {
+ intermediateClassIvar = 3.14;
+ // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+ // CHECK: getelementptr inbounds i8, ptr %0, i64 32
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassPropertyMethod]"
+- (void)intermediateClassPropertyMethod {
+ self.intermediateProperty = 0;
+ // CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_
+ // CHECK: call void @objc_msgSend(ptr noundef %0, ptr noundef %1, ptr noundef null)
+}
+
+// CHECK-LABEL: define internal void @"\01-[IntermediateClass intermediateClassPropertyMethodDirect]"
+- (void)intermediateClassPropertyMethodDirect {
+ _intermediateProperty = 0;
+ // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass._intermediateProperty"
+ // CHECK: getelementptr inbounds i8, ptr %0, i64 48
}
@end
+ at interface SubClass : IntermediateClass {
+ double subClassIvar;
+}
+ at property (nonatomic, assign) SubClass *subClassProperty;
+ at end
+
+ at implementation SubClass
+
+// CHECK-LABEL: define internal void @"\01-[SubClass subclassVar]"
+- (void)subclassVar {
+ subClassIvar = 6.28;
+ // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass
+ // CHECK: getelementptr inbounds i8, ptr %0, i64 56
+}
+
+// CHECK-LABEL: define internal void @"\01-[SubClass intermediateSubclassVar]"
+-(void)intermediateSubclassVar {
+ intermediateClassIvar = 3.14;
+ // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_IntermediateClass
+ // CHECK: getelementptr inbounds i8, ptr %0, i64 32
+}
+
+// Implicit synthesized method here:
+// CHECK-LABEL: define internal ptr @"\01-[SubClass subClassProperty]"
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+// CHECK: getelementptr inbounds i8, ptr %0, i64 64
+
+// CHECK-LABEL: define internal void @"\01-[SubClass setSubClassProperty:]"
+// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_SubClass._subClassProperty"
+// CHECK: getelementptr inbounds i8, ptr %1, i64 64
+ at end
+
@interface NotNSObject {
int these, might, change;
}
@@ -31,6 +131,8 @@ @interface NotStaticLayout : NotNSObject
@implementation NotStaticLayout {
int not_static_layout_ivar;
}
+
+// CHECK-LABEL: define internal void @"\01-[NotStaticLayout meth]"
-(void)meth {
not_static_layout_ivar = 0;
// CHECK: load i64, ptr @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar
``````````
</details>
https://github.com/llvm/llvm-project/pull/84093
More information about the llvm-branch-commits
mailing list