[clang] [ObjC] Expand isClassLayoutKnownStatically to base classes as long as the implementation of it is known (PR #85465)

via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 16 18:21:38 PST 2024


https://github.com/AreaZR updated https://github.com/llvm/llvm-project/pull/85465

>From ffbc1da0d631f3969be4f470f5f446b34adf49fc Mon Sep 17 00:00:00 2001
From: Rose <gfunni234 at gmail.com>
Date: Fri, 15 Mar 2024 16:43:10 -0400
Subject: [PATCH] [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.
---
 clang/lib/CodeGen/CGObjCMac.cpp               |  9 ++++-
 clang/test/CodeGenObjC/arc-blocks.m           |  8 ++---
 clang/test/CodeGenObjC/arc-property.m         | 22 +++++-------
 clang/test/CodeGenObjC/arc-weak-property.m    |  5 ++-
 clang/test/CodeGenObjC/arc.m                  | 18 ++++------
 clang/test/CodeGenObjC/arm64-int32-ivar.m     |  5 ++-
 .../test/CodeGenObjC/bitfield-ivar-offsets.m  |  5 ++-
 .../constant-non-fragile-ivar-offset.m        | 34 +++++++++++++++++--
 clang/test/CodeGenObjC/direct-method.m        |  3 +-
 clang/test/CodeGenObjC/hidden-visibility.m    |  2 +-
 clang/test/CodeGenObjC/interface-layout-64.m  | 16 +++++----
 .../CodeGenObjC/ivar-base-as-invariant-load.m |  5 ++-
 clang/test/CodeGenObjC/metadata-symbols-64.m  |  4 +--
 .../nontrivial-c-struct-property.m            |  4 ++-
 .../CodeGenObjC/objc-asm-attribute-test.m     |  5 +--
 clang/test/CodeGenObjC/ubsan-bool.m           |  4 ++-
 16 files changed, 96 insertions(+), 53 deletions(-)

diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 7b85dcc2c7984f..6ad08c52256ae9 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -1592,6 +1592,11 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
   bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
     // Test a class by checking its superclasses up to
     // its base class if it has one.
+
+    // Cannot check a null class
+    if (!ID)
+      return false;
+
     for (; ID; ID = ID->getSuperClass()) {
       // The layout of base class NSObject
       // is guaranteed to be statically known
@@ -1603,7 +1608,9 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
       if (!ID->getImplementation())
         return false;
     }
-    return false;
+
+    // We know the layout of all the intermediate classes and superclasses.
+    return true;
   }
 
 public:
diff --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m
index bed55bf18fe59f..72bf35c2e117e5 100644
--- a/clang/test/CodeGenObjC/arc-blocks.m
+++ b/clang/test/CodeGenObjC/arc-blocks.m
@@ -422,16 +422,16 @@ @interface Test12
 @implementation Test12
 @synthesize ablock, nblock;
 // CHECK:    define internal ptr @"\01-[Test12 ablock]"(
-// CHECK:    call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, i1 noundef zeroext true)
+// CHECK:    call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, i1 noundef zeroext true)
 
 // CHECK:    define internal void @"\01-[Test12 setAblock:]"(
-// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
+// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
 
 // CHECK:    define internal ptr @"\01-[Test12 nblock]"(
-// CHECK:    %add.ptr = getelementptr inbounds i8, ptr %0, i64 %ivar
+// CHECK:    %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
 
 // CHECK:    define internal void @"\01-[Test12 setNblock:]"(
-// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
+// CHECK:    call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 8, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
 @end
 
 void test13(id x) {
diff --git a/clang/test/CodeGenObjC/arc-property.m b/clang/test/CodeGenObjC/arc-property.m
index f57be6b4f6be41..3209993cc6d32c 100644
--- a/clang/test/CodeGenObjC/arc-property.m
+++ b/clang/test/CodeGenObjC/arc-property.m
@@ -22,16 +22,14 @@ @implementation Test1
 @end
 //   The getter should be a simple load.
 // CHECK:    define internal ptr @"\01-[Test1 pointer]"(
-// CHECK:      [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 [[OFFSET]]
+// CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 0
 // CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T1]], align 8
 // CHECK-NEXT: ret ptr [[T3]]
 
 //   The setter should be using objc_setProperty.
 // CHECK:    define internal void @"\01-[Test1 setPointer:]"(
-// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
-// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
-// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext false, i1 noundef zeroext false)
+// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
+// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext false)
 // CHECK-NEXT: ret void
 
 
@@ -52,26 +50,22 @@ - (void) test {
 // CHECK:    define internal void @"\01-[Test2 test]"(
 // CHECK:      [[T0:%.*]] = load ptr, ptr @theGlobalClass, align 8
 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T3]], ptr [[T0]]) [[NUW:#[0-9]+]]
 // CHECK-NEXT: ret void
 
 // CHECK:    define internal ptr @"\01-[Test2 theClass]"(
-// CHECK:      [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
-// CHECK-NEXT: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef [[OFFSET]], i1 noundef zeroext true)
+// CHECK: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef 0, i1 noundef zeroext true)
 // CHECK-NEXT: ret ptr [[T0]]
 
 // CHECK:    define internal void @"\01-[Test2 setTheClass:]"(
-// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
-// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
-// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext true, i1 noundef zeroext true)
+// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
+// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
 // CHECK-NEXT: ret void
 
 // CHECK:    define internal void @"\01-[Test2 .cxx_destruct]"(
 // CHECK:      [[T0:%.*]] = load ptr, ptr
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
-// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T2]], ptr null) [[NUW]]
 // CHECK-NEXT: ret void
 
diff --git a/clang/test/CodeGenObjC/arc-weak-property.m b/clang/test/CodeGenObjC/arc-weak-property.m
index 8c268c1b9deea9..cdec1cdeabbb1c 100644
--- a/clang/test/CodeGenObjC/arc-weak-property.m
+++ b/clang/test/CodeGenObjC/arc-weak-property.m
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
 
- at interface WeakPropertyTest {
+ at interface SuperClass
+ at end
+
+ at interface WeakPropertyTest : SuperClass {
     __weak id PROP;
 }
 @property () __weak id PROP;
diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m
index 8eaca8ea1c68c9..6dbd5057314e41 100644
--- a/clang/test/CodeGenObjC/arc.m
+++ b/clang/test/CodeGenObjC/arc.m
@@ -577,8 +577,7 @@ @interface Test26 { id x[4]; } @end
 @implementation Test26 @end
 // CHECK:    define internal void @"\01-[Test26 .cxx_destruct]"(
 // CHECK:      [[SELF:%.*]] = load ptr, ptr
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test26.x"
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x ptr], ptr [[T1]], i32 0, i32 0
 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 4
 // CHECK-NEXT: br label
@@ -616,8 +615,7 @@ @implementation Test28
 @end
 // CHECK:    define internal void @"\01-[Test28 .cxx_destruct]"
 // CHECK:      [[SELF:%.*]] = load ptr, ptr
-// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test28.prop"
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null)
 // CHECK-NEXT: ret void
 
@@ -738,8 +736,7 @@ - (id) init {
 
 // Assignment.
 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]]
-// CHECK-NEXT: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test30.helper"
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[IVAR]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
 // CHECK-NEXT#: [[T5:%.*]] = load ptr, ptr [[T3]]
 // CHECK-NEXT#: [[T6:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]])
 // CHECK-NEXT#: call void @llvm.objc.release(ptr [[T5]])
@@ -1137,23 +1134,20 @@ @implementation Test57
 @end
 // CHECK: define internal ptr @"\01-[Test57 strong]"(
 // CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.strong"
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
 // CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
 // CHECK-NEXT: ret ptr [[T5]]
 
 // CHECK: define internal ptr @"\01-[Test57 weak]"(
 // CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.weak"
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8
 // CHECK-NEXT: [[T5:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T3]])
 // CHECK-NEXT: [[T6:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T5]])
 // CHECK-NEXT: ret ptr [[T6]]
 
 // CHECK: define internal ptr @"\01-[Test57 unsafe]"(
 // CHECK:      [[T0:%.*]] = load ptr, ptr {{%.*}}
-// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.unsafe"
-// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 16
 // CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
 // CHECK-NEXT: ret ptr [[T5]]
 
diff --git a/clang/test/CodeGenObjC/arm64-int32-ivar.m b/clang/test/CodeGenObjC/arm64-int32-ivar.m
index 85f570ae3cbc8b..04aa2d7bcbda07 100644
--- a/clang/test/CodeGenObjC/arm64-int32-ivar.m
+++ b/clang/test/CodeGenObjC/arm64-int32-ivar.m
@@ -2,7 +2,10 @@
 
 // CHECK: @"OBJC_IVAR_$_I.IVAR2" = global i32 8
 // CHECK: @"OBJC_IVAR_$_I.IVAR1" = global i32 0
- at interface I
+ at interface SuperClass
+ at end
+
+ at interface I : SuperClass
 {
 	id IVAR1;
 	id IVAR2;
diff --git a/clang/test/CodeGenObjC/bitfield-ivar-offsets.m b/clang/test/CodeGenObjC/bitfield-ivar-offsets.m
index f17d56af19ce38..699e0cc82e7d3c 100644
--- a/clang/test/CodeGenObjC/bitfield-ivar-offsets.m
+++ b/clang/test/CodeGenObjC/bitfield-ivar-offsets.m
@@ -8,7 +8,10 @@
 // RUN: grep -F '@"OBJC_IVAR_$_I0._b4" = global i64 7, section "__DATA, __objc_ivar", align 8' %t
 // RUN: not grep -F '@"OBJC_IVAR_$_I0." = global' %t
 
- at interface I0 {
+ at interface SuperClass
+ at end
+
+ at interface I0 : SuperClass {
   unsigned _b0:4;
   unsigned _b1:5;
   unsigned _b2:5;
diff --git a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
index 8d55e6c7d23081..814c36c9780b52 100644
--- a/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
+++ b/clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m
@@ -8,6 +8,12 @@
 // 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_$_RootClass.these" = constant i64 0
+// CHECK: @"OBJC_IVAR_$_RootClass.never" = constant i64 4
+// CHECK: @"OBJC_IVAR_$_RootClass.change" = constant i64 8
+// CHECK: @"OBJC_IVAR_$_StillStaticLayout.static_layout_ivar" = hidden constant i64 12
+
 // CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
 
 @interface NSObject {
@@ -120,12 +126,34 @@ -(void)intermediateSubclassVar {
 // CHECK: getelementptr inbounds i8, ptr %1, i64 64
 @end
 
- at interface NotNSObject {
-  int these, might, change;
+ __attribute((objc_root_class))  @interface RootClass {
+  int these, never, change;
 }
 @end
 
- at interface NotStaticLayout : NotNSObject
+ at implementation RootClass 
+ at end
+
+ at interface StillStaticLayout : RootClass
+ at end
+
+ at implementation StillStaticLayout {
+  int static_layout_ivar;
+}
+
+// CHECK-LABEL: define internal void @"\01-[StillStaticLayout meth]"
+-(void)meth {
+  static_layout_ivar = 0;
+  // CHECK-NOT: load i64, ptr @"OBJC_IVAR_$StillStaticLayout.static_layout_ivar
+}
+ at end
+
+ at interface NotNSObject
+ at end
+
+ at interface NotStaticLayout : NotNSObject {
+  int these, might, change;
+}
 @end
 
 @implementation NotStaticLayout {
diff --git a/clang/test/CodeGenObjC/direct-method.m b/clang/test/CodeGenObjC/direct-method.m
index 028a0888d594ee..c8215f2505b493 100644
--- a/clang/test/CodeGenObjC/direct-method.m
+++ b/clang/test/CodeGenObjC/direct-method.m
@@ -167,8 +167,7 @@ - (void)accessCmd __attribute__((objc_direct)) {
 // CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(
 // CHECK-LABEL: objc_direct_method.cont:
 // CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,
-// CHECK-NEXT: [[IVAR:%.*]] = load {{.*}} @"OBJC_IVAR_$_Root._objectProperty",
-// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef [[IVAR]], {{.*}})
+// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef 8, {{.*}})
 
 @interface Foo : Root {
   id __strong _cause_cxx_destruct;
diff --git a/clang/test/CodeGenObjC/hidden-visibility.m b/clang/test/CodeGenObjC/hidden-visibility.m
index 12338d6bc9d5d5..0c0dad0064806a 100644
--- a/clang/test/CodeGenObjC/hidden-visibility.m
+++ b/clang/test/CodeGenObjC/hidden-visibility.m
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple i386-apple-macosx -fvisibility=hidden -emit-llvm -o - %s | FileCheck %s
-// CHECK: @"OBJC_IVAR_$_I.P" = hidden
 // CHECK: @"OBJC_CLASS_$_I" = hidden
 // CHECK: @"OBJC_METACLASS_$_I" = hidden
+// CHECK: @"OBJC_IVAR_$_I.P" = hidden
 // CHECK: @"_OBJC_PROTOCOL_$_Prot0" = weak hidden
 
 @interface I {
diff --git a/clang/test/CodeGenObjC/interface-layout-64.m b/clang/test/CodeGenObjC/interface-layout-64.m
index 4b41cf855ed3bd..1a1d3b19ca0087 100644
--- a/clang/test/CodeGenObjC/interface-layout-64.m
+++ b/clang/test/CodeGenObjC/interface-layout-64.m
@@ -10,11 +10,11 @@
 // CHECK: @"OBJC_IVAR_$_I5._iv5" = global i64 14, section "__DATA, __objc_ivar", align 8
 // CHECK: _OBJC_CLASS_RO_$_I5" = internal global {{.*}} { i32 0, i32 14, i32 24, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I6.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I6" = internal global {{.*}} { i32 2, i32 0, i32 1, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I6" = internal global {{.*}} { i32 0, i32 0, i32 1, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I8.b" = global i64 8, section "__DATA, __objc_ivar", align 8
 // CHECK: _OBJC_CLASS_RO_$_I8" = internal global {{.*}} { i32 0, i32 8, i32 16, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I9.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I9" = internal global {{.*}} { i32 2, i32 0, i32 4, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I9" = internal global {{.*}} { i32 0, i32 0, i32 4, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I10.iv1" = global i64 4, section "__DATA, __objc_ivar", align 8
 // CHECK: _OBJC_CLASS_RO_$_I10" = internal global {{.*}} { i32 0, i32 4, i32 5, {{.*}}
 // CHECK: _OBJC_CLASS_RO_$_I11" = internal global {{.*}} { i32 0, i32 5, i32 5, {{.*}}
@@ -28,11 +28,15 @@
     gcc -m64 -S -o - interface-layout-64.m | grep '^l{{.*}}_CLASS_RO_$_I[0-9]*' -A 3
  */
 
+ at interface SuperClass
+ at end
+
 struct s0 {
   double x;
 };
 
- at interface I2 {
+
+ at interface I2 : SuperClass {
   struct s0 _iv1;
 }
 @end
@@ -74,7 +78,7 @@ @implementation I5
 @end
 
 // The size rounds up to the next available byte.
- at interface I6 {
+ at interface I6 : SuperClass {
   unsigned iv0 : 2;
 }
 @end
@@ -82,7 +86,7 @@ @implementation I6
 @end
 
 // The start of the subclass includes padding for its own alignment.
- at interface I7 {
+ at interface I7 : SuperClass {
   char a;
 }
 @end
@@ -94,7 +98,7 @@ @implementation I8
 @end
 
 // Padding bit-fields
- at interface I9 {
+ at interface I9 : SuperClass {
   unsigned iv0 : 2;
   unsigned : 0;
 }
diff --git a/clang/test/CodeGenObjC/ivar-base-as-invariant-load.m b/clang/test/CodeGenObjC/ivar-base-as-invariant-load.m
index 5ff13a2a1890aa..499d34d1864588 100644
--- a/clang/test/CodeGenObjC/ivar-base-as-invariant-load.m
+++ b/clang/test/CodeGenObjC/ivar-base-as-invariant-load.m
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -emit-llvm  -triple x86_64-apple-darwin -x objective-c %s -o - | FileCheck %s
 
- at interface A {
+ at interface SuperClass
+ at end
+
+ at interface A : SuperClass {
         struct {
                 unsigned char a : 1;
                 unsigned char b : 1;
diff --git a/clang/test/CodeGenObjC/metadata-symbols-64.m b/clang/test/CodeGenObjC/metadata-symbols-64.m
index 96a79470bfdde4..0333506216daa0 100644
--- a/clang/test/CodeGenObjC/metadata-symbols-64.m
+++ b/clang/test/CodeGenObjC/metadata-symbols-64.m
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: @"OBJC_IVAR_$_A._ivar" ={{.*}} global {{.*}} section "__DATA, __objc_ivar", align 8
 // CHECK: @_objc_empty_cache = external global
 // CHECK: @_objc_empty_vtable = external global
-// CHECK: @"OBJC_CLASS_$_A" ={{.*}} global
+// CHECK: @"OBJC_CLASS_$_A" = global
 // CHECK: @"OBJC_METACLASS_$_A" ={{.*}} global {{.*}} section "__DATA, __objc_data", align 8
 // CHECK: @OBJC_CLASS_NAME_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1
 // CHECK: @OBJC_METH_VAR_NAME_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
@@ -16,6 +15,7 @@
 // CHECK: @"_OBJC_CLASS_PROTOCOLS_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
 // CHECK: @"_OBJC_METACLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
 // CHECK: @"_OBJC_$_INSTANCE_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"OBJC_IVAR_$_A._ivar" ={{.*}} constant {{.*}} section "__DATA, __objc_ivar", align 
 // CHECK: @"_OBJC_$_INSTANCE_VARIABLES_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
 // CHECK: @OBJC_PROP_NAME_ATTR_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
 // CHECK: @"_OBJC_$_PROP_LIST_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
diff --git a/clang/test/CodeGenObjC/nontrivial-c-struct-property.m b/clang/test/CodeGenObjC/nontrivial-c-struct-property.m
index ef1726effe2bc3..4ddb16c6e3381c 100644
--- a/clang/test/CodeGenObjC/nontrivial-c-struct-property.m
+++ b/clang/test/CodeGenObjC/nontrivial-c-struct-property.m
@@ -1,10 +1,12 @@
 // RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+ at interface SuperClass
+ at end
 
 typedef struct {
   id x;
 } S0;
 
- at interface C {
+ at interface C : SuperClass {
   S0 _p1;
 }
 @property(nonatomic) S0 nonatomic;
diff --git a/clang/test/CodeGenObjC/objc-asm-attribute-test.m b/clang/test/CodeGenObjC/objc-asm-attribute-test.m
index e57e42535f6727..e16f11e30163c0 100644
--- a/clang/test/CodeGenObjC/objc-asm-attribute-test.m
+++ b/clang/test/CodeGenObjC/objc-asm-attribute-test.m
@@ -57,7 +57,6 @@ id Test16877359(void) {
     return [SLREarth alloc];
 }
 
-// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" ={{.*}} global i64 0
 // CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" ={{.*}} global %struct._class_t
 // CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" ={{.*}} global %struct._class_t
 
@@ -65,10 +64,12 @@ id Test16877359(void) {
 // CHECK-NEXT: @OBJC_PROP_NAME_ATTR_.11 = private unnamed_addr constant [7 x i8] c"T@,?,&\00"
 // CHECK: @"_OBJC_$_PROP_LIST_MySecretNamespace.Protocol2" ={{.*}} [%struct._prop_t { ptr @OBJC_PROP_NAME_ATTR_, ptr @OBJC_PROP_NAME_ATTR_.11 }]
 
+// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" ={{.*}} constant i64 0
+
 // CHECK: private unnamed_addr constant [42 x i8] c"T@\22MySecretNamespace.Message\22,&,V_msgProp\00"
 // CHECK: private unnamed_addr constant [76 x i8] c"T@\22MySecretNamespace.Message<MySecretNamespace.Protocol3>\22,&,V_msgProtoProp\00"
 // CHECK: private unnamed_addr constant [50 x i8] c"T@\22<MySecretNamespace.Protocol3>\22,&,V_idProtoProp\00"
 
 // CHECK: @"OBJC_CLASS_$_foo" = external global %struct._class_t
 // CHECK: define internal ptr @"\01-[Message MyMethod]"
-// CHECK: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR"
+// CHECK: [[IVAR:%.*]] = load ptr, ptr {{.*}}
diff --git a/clang/test/CodeGenObjC/ubsan-bool.m b/clang/test/CodeGenObjC/ubsan-bool.m
index e33e3e0ef49633..ca63c66fca5dc7 100644
--- a/clang/test/CodeGenObjC/ubsan-bool.m
+++ b/clang/test/CodeGenObjC/ubsan-bool.m
@@ -31,7 +31,9 @@ BOOL f2(struct S1 *s) {
 }
 
 #ifdef __OBJC__
- at interface I1 {
+ at interface SuperClass
+ at end
+ at interface I1 : SuperClass {
 @public
   BOOL b1 : 1;
 }



More information about the cfe-commits mailing list