Skip to content

Runtime: Fix breakage when generic subclasses directly inherit NSObject (3.0) #4880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions lib/IRGen/GenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,13 @@ namespace {
assert(superclass);

if (superclass->hasClangNode()) {
// As a special case, assume NSObject has a fixed layout.
if (superclass->getName() !=
IGM.Context.getSwiftId(KnownFoundationEntity::NSObject)) {
// If the superclass was imported from Objective-C, its size is
// not known at compile time. However, since the field offset
// vector only stores offsets of stored properties defined in
// Swift, we don't have to worry about indirect indexing of
// the field offset vector.
ClassHasFixedSize = false;
}
// If the superclass was imported from Objective-C, its size is
// not known at compile time. However, since the field offset
// vector only stores offsets of stored properties defined in
// Swift, we don't have to worry about indirect indexing of
// the field offset vector.
ClassHasFixedSize = false;

} else if (IGM.isResilient(superclass, ResilienceExpansion::Maximal)) {
ClassMetadataRequiresDynamicInitialization = true;

Expand Down
10 changes: 7 additions & 3 deletions test/IRGen/class_resilience_objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
import Foundation

public class FixedLayoutObjCSubclass : NSObject {
// This field uses constant direct access because NSObject has fixed layout.
// This field could use constant direct access because NSObject has
// fixed layout, but we don't allow that right now.
public final var field: Int32 = 0
};

// CHECK-LABEL: define hidden void @_TF21class_resilience_objc29testConstantDirectFieldAccessFCS_23FixedLayoutObjCSubclassT_(%C21class_resilience_objc23FixedLayoutObjCSubclass*)
// CHECK: [[FIELD_ADDR:%.*]] = getelementptr inbounds %C21class_resilience_objc23FixedLayoutObjCSubclass, %C21class_resilience_objc23FixedLayoutObjCSubclass* %0, i32 0, i32 1
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* %1, i32 0, i32 0
// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC21class_resilience_objc23FixedLayoutObjCSubclass5fieldVs5Int32
// CHECK-NEXT: [[OBJECT:%.*]] = bitcast %C21class_resilience_objc23FixedLayoutObjCSubclass* %0 to i8*
// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i8, i8* [[OBJECT]], [[INT]] [[OFFSET]]
// CHECK-NEXT: [[FIELD_ADDR:%.*]] = bitcast i8* [[ADDR]] to %Vs5Int32*
// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_ADDR]], i32 0, i32 0
// CHECK-NEXT: store i32 10, i32* [[PAYLOAD_ADDR]]

func testConstantDirectFieldAccess(_ o: FixedLayoutObjCSubclass) {
Expand Down
16 changes: 16 additions & 0 deletions test/Interpreter/generic_objc_subclass.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,19 @@ fixedB.third = 17

// CHECK: (101, 0, 0, 0, 16, [19, 84], 17)
print(fixedG())

// Problem with field alignment in direct generic subclass of NSObject -
// <https://bugs.swift.org/browse/SR-2586>
public class PandorasBox<T>: NSObject {
final public var value: T

public init(_ value: T) {
// Uses ConstantIndirect access pattern
self.value = value
}
}

let c = PandorasBox(30)
// CHECK: 30
// Uses ConstantDirect access pattern
print(c.value)