From 2546c2d78d1d7c14958c9f66819796240ae6ca72 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 6 Oct 2020 23:01:47 -0400 Subject: [PATCH] Fetch associated types abstractly when fetching an associated conformance. By default, emitTypeMetadataRef does a blocking request for complete metadata, which is the right thing to do for most purposes in IRGen. Unfortunately, it's actively dangerous in code that can be called during metadata completion, like an associated conformance accessor, because it can cause artificial dependency cycles that the runtime isn't equipped to detect, much less solve. This is a partial fix for rdar://69901318, which also exposes a bad metadata access path that seems to be causing an artificial problem. --- lib/IRGen/GenProto.cpp | 6 ++++-- test/IRGen/associated_types.swift | 3 ++- test/IRGen/generic_structs.sil | 3 --- test/IRGen/generic_structs_future.sil | 3 --- test/IRGen/same_type_constraints.swift | 2 +- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 706e64cf6d74e..1e20fcb9babc2 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2567,8 +2567,10 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF, if (!source) return MetadataResponse(); - auto sourceMetadata = IGF.emitTypeMetadataRef(sourceType); - auto associatedMetadata = IGF.emitTypeMetadataRef(sourceKey.Type); + auto sourceMetadata = + IGF.emitAbstractTypeMetadataRef(sourceType); + auto associatedMetadata = + IGF.emitAbstractTypeMetadataRef(sourceKey.Type); auto sourceWTable = source.getMetadata(); AssociatedConformance associatedConformanceRef(sourceProtocol, diff --git a/test/IRGen/associated_types.swift b/test/IRGen/associated_types.swift index 5d0953f1a0e6c..f5d152beb7d1f 100644 --- a/test/IRGen/associated_types.swift +++ b/test/IRGen/associated_types.swift @@ -75,8 +75,9 @@ func testFastRuncible(_ t: T, u: U) // 1. Get the type metadata for U.RuncerType.Runcee. // 1a. Get the type metadata for U.RuncerType. // Note that we actually look things up in T, which is going to prove unfortunate. -// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 0, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]] +// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness([[INT]] 255, i8** %T.Runcible, %swift.type* %T, %swift.protocol_requirement* getelementptr{{.*}}i32 12), i32 -1), %swift.protocol_requirement* getelementptr inbounds (<{{.*}}>, <{{.*}}>* @"$s16associated_types8RuncibleMp", i32 0, i32 14)) [[NOUNWIND_READNONE:#.*]] // CHECK-NEXT: %T.RuncerType = extractvalue %swift.metadata_response [[T2]], 0 +// CHECK-NEXT: extractvalue %swift.metadata_response [[T2]], 1 // 2. Get the witness table for U.RuncerType.Runcee : Speedy // 2a. Get the protocol witness table for U.RuncerType : FastRuncer. // CHECK-NEXT: %T.RuncerType.FastRuncer = call swiftcc i8** @swift_getAssociatedConformanceWitness(i8** %U.FastRuncible, %swift.type* %U, %swift.type* %T.RuncerType diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil index 39dd44b5e1243..a90d4f825c479 100644 --- a/test/IRGen/generic_structs.sil +++ b/test/IRGen/generic_structs.sil @@ -246,9 +246,6 @@ struct GenericLayoutWithAssocType { // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s15generic_structs26GenericLayoutWithAssocTypeVMr"( -// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState(i64 0, %swift.type* %T) -// CHECK: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 - // CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1 // CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]] // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8** diff --git a/test/IRGen/generic_structs_future.sil b/test/IRGen/generic_structs_future.sil index e9b49c850e0e9..8874a61ba6509 100644 --- a/test/IRGen/generic_structs_future.sil +++ b/test/IRGen/generic_structs_future.sil @@ -247,9 +247,6 @@ struct GenericLayoutWithAssocType { // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMr"( -// CHECK: [[T0:%.*]] = call{{( tail)?}} swiftcc %swift.metadata_response @swift_checkMetadataState(i64 0, %swift.type* %T) -// CHECK: [[T_CHECKED:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 - // CHECK: [[T0_GEP:%.*]] = getelementptr inbounds i8*, i8** %T.ParentHasAssociatedType, i32 1 // CHECK: [[T0:%.*]] = load i8*, i8** [[T0_GEP]] // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i8** diff --git a/test/IRGen/same_type_constraints.swift b/test/IRGen/same_type_constraints.swift index a3ac8a52c7a99..17ba3f5161332 100644 --- a/test/IRGen/same_type_constraints.swift +++ b/test/IRGen/same_type_constraints.swift @@ -67,7 +67,7 @@ where Self : CodingType, print(Self.ValueType.self) } -// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* %"GenericKlazz.Data", %swift.type* nocapture readonly %"GenericKlazz", i8** nocapture readnone %"GenericKlazz.E") [[ATTRS:#[0-9]+]] { +// OSIZE: define internal swiftcc i8** @"$s21same_type_constraints12GenericKlazzCyxq_GAA1EAA4Data_AA0F4TypePWT"(%swift.type* readnone %"GenericKlazz.Data", %swift.type* nocapture readonly %"GenericKlazz", i8** nocapture readnone %"GenericKlazz.E") [[ATTRS:#[0-9]+]] { // OSIZE: [[ATTRS]] = {{{.*}}noinline // Check that same-typing two generic parameters together lowers correctly.