Skip to content

Commit f1a3673

Browse files
committed
IRGen: Map type into context before asking for class layout.
Asking for the layout of the interface type apparently gives the wrong answer, causing key paths to access stored properties of generic classes using the wrong strategy. Fixes SR-10167 | rdar://problem/49230751.
1 parent 911cd53 commit f1a3673

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

lib/IRGen/GenKeyPath.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,8 +761,13 @@ emitKeyPathComponent(IRGenModule &IGM,
761761
assert(currentBaseTy->getClassOrBoundGenericClass() == propertyBaseDecl);
762762
loweredBaseTy =
763763
IGM.getLoweredType(AbstractionPattern::getOpaque(), currentBaseTy);
764+
765+
auto loweredBaseContextTy = SILType::getPrimitiveObjectType(
766+
GenericEnvironment::mapTypeIntoContext(genericEnv,
767+
loweredBaseTy.getASTType())
768+
->getCanonicalType());
764769

765-
switch (getClassFieldAccess(IGM, loweredBaseTy, property)) {
770+
switch (getClassFieldAccess(IGM, loweredBaseContextTy, property)) {
766771
case FieldAccess::ConstantDirect: {
767772
// Known constant fixed offset.
768773
auto offset = tryEmitConstantClassFragilePhysicalMemberOffset(IGM,

test/IRGen/keypaths.sil

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public class C: Hashable {
2727
public func hash(into hasher: inout Hasher)
2828
public static func ==(_: C, _: C) -> Bool
2929
}
30+
public class GC<T> {
31+
public final var x: T
32+
}
3033

3134
public struct G<T> {
3235
public var x: T { get set }
@@ -299,6 +302,14 @@ sil_vtable C2 {}
299302
// CHECK-32-SAME: i32 24 }>
300303
// CHECK-64-SAME: i32 48 }>
301304

305+
// -- %gcx: GC<T>.x
306+
// CHECK: [[KP_GCX:@keypath(\..*)?]] = private global <{ {{.*}} }> <{
307+
// CHECK-SAME: @"generic environment l"
308+
// CHECK-SAME: @"symbolic 8keypaths2GCCyxG"
309+
// CHECK-SAME: @"symbolic x"
310+
// -- class with runtime-resolved offset, mutable
311+
// CHECK-SAME: <i32 0x3fffffe>
312+
302313
// CHECK-LABEL: @"generic environment SHRzSHR_r0_l" = linkonce_odr hidden constant
303314
// CHECK-SAME: i32 8193, i16 2, i8 -128, i8 -128, i32 128
304315

@@ -421,6 +432,14 @@ entry:
421432
return undef : $()
422433
}
423434

435+
sil @generic_class_stored_final : $@convention(thin) <T> () -> () {
436+
entry:
437+
%gcx = keypath $ReferenceWritableKeyPath<GC<T>, T>, <T> (root $GC<T>; stored_property #GC.x: $T) <T>
438+
439+
return undef : $()
440+
}
441+
442+
424443
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics
425444
sil @computed_property_generics : $@convention(thin) <T, U> () -> () {
426445
entry:

0 commit comments

Comments
 (0)