]> granicus.if.org Git - clang/commitdiff
Fix the emission of ARC-style ivar layouts in the fragile runtime
authorJohn McCall <rjmccall@apple.com>
Thu, 19 Nov 2015 02:27:55 +0000 (02:27 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 19 Nov 2015 02:27:55 +0000 (02:27 +0000)
to start at the offset of the first ivar instead of the rounded-up
end of the superclass.  The latter could include a large amount of
tail padding because of a highly-aligned ivar, and subclass ivars
can be laid out within that.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253533 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjCMac.cpp
test/CodeGenObjC/mrc-weak.m

index a5f504e141cc171241d3ad007271249311d612aa..dad172b5651f0c493e787d585a0427a2d894c3fa 100644 (file)
@@ -4927,7 +4927,7 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
   // ARC layout strings only include the class's ivars.  In non-fragile
   // runtimes, that means starting at InstanceStart, rounded up to word
   // alignment.  In fragile runtimes, there's no InstanceStart, so it means
-  // starting at the end of the superclass, rounded up to word alignment.
+  // starting at the offset of the first ivar, rounded up to word alignment.
   //
   // MRC weak layout strings follow the ARC style.
   CharUnits baseOffset;
@@ -4938,10 +4938,9 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
 
     if (isNonFragileABI()) {
       baseOffset = beginOffset; // InstanceStart
-    } else if (auto superClass = OI->getSuperClass()) {
-      auto startOffset =
-        CGM.getContext().getASTObjCInterfaceLayout(superClass).getSize();
-      baseOffset = startOffset;
+    } else if (!ivars.empty()) {
+      baseOffset =
+        CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
     } else {
       baseOffset = CharUnits::Zero();
     }
index f9c4ff1b12356c816157bcd0713c78b811ae3004..9072b1a08325eb9c8fb32d1d50a1a507bb561d0f 100644 (file)
@@ -6,6 +6,26 @@
 - (void) run;
 @end
 
+// The ivars in HighlyAlignedSubclass should be placed in the tail-padding
+// of the superclass.  Ensure that they're still covered by layouts.
+@interface HighlyAligned : Object {
+  __attribute__((aligned(32))) void *array[2];
+}
+@end
+// CHECK-MODERN: @"OBJC_IVAR_$_HighlyAlignedSubclass.ivar2" = global i64 24,
+// CHECK-MODERN: @"OBJC_IVAR_$_HighlyAlignedSubclass.ivar" = global i64 16,
+// CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\02\00"
+// CHECK-MODERN: @"\01l_OBJC_CLASS_RO_$_HighlyAlignedSubclass" = {{.*}} {
+// CHECK-FRAGILE: @OBJC_INSTANCE_VARIABLES_HighlyAlignedSubclass = {{.*}}, i32 8 }, {{.*}}, i32 12 }]
+// CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\02\00"
+// CHECK-FRAGILE: @OBJC_CLASS_HighlyAlignedSubclass
+@interface HighlyAlignedSubclass : HighlyAligned {
+  __weak id ivar;
+  __weak id ivar2;
+}
+@end
+@implementation HighlyAlignedSubclass @end
+
 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
 // CHECK-MODERN: @"\01l_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772
 //   772 == 0x304