diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 4e5bf67157a..82239aad53c 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -1918,9 +1918,7 @@ namespace { Flags = Flags.withNumConditionalRequirements(numConditional); // Relative reference to the witness table. - auto witnessTableRef = - ConstantReference(Description.pattern, ConstantReference::Direct); - B.addRelativeAddress(witnessTableRef); + B.addRelativeAddressOrNull(Description.pattern); } void addFlags() { @@ -2244,19 +2242,27 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) { // Produce the initializer value. auto initializer = wtableContents.finishAndCreateFuture(); - bool isDependent = isDependentConformance(conf, /*considerResilience=*/true); - auto global = cast( - isDependent - ? getAddrOfWitnessTablePattern(cast(conf), - initializer) - : getAddrOfWitnessTable(conf, initializer)); - global->setConstant(isConstantWitnessTable(wt)); - global->setAlignment(getWitnessTableAlignment().getValue()); + llvm::GlobalVariable *global = nullptr; + unsigned tableSize; + if (!isResilientConformance(conf)) { + bool isDependent = + isDependentConformance(conf, /*considerResilience=*/false); + global = cast( + isDependent + ? getAddrOfWitnessTablePattern(cast(conf), + initializer) + : getAddrOfWitnessTable(conf, initializer)); + global->setConstant(isConstantWitnessTable(wt)); + global->setAlignment(getWitnessTableAlignment().getValue()); + tableSize = wtableBuilder.getTableSize(); + } else { + initializer.abandon(); + tableSize = 0; + } // Collect the information that will go into the protocol conformance // descriptor. - ConformanceDescription description(conf, wt, global, - wtableBuilder.getTableSize(), + ConformanceDescription description(conf, wt, global, tableSize, wtableBuilder.getTablePrivateSize(), wtableBuilder.requiresSpecialization(), isDependentConformance( diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index 2dc014d78db..ab8eb06b678 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -4069,12 +4069,18 @@ WitnessTableCacheEntry::allocate( // Advance the address point; the private storage area is accessed via // negative offsets. auto table = fullTable + privateSizeInWords; - auto pattern = reinterpret_cast( - &*conformance->getWitnessTablePattern()); - - // Fill in the provided part of the requirements from the pattern. - for (size_t i = 0, e = numPatternWitnesses; i < e; ++i) { - table[i] = pattern[i]; + if (auto pattern = + reinterpret_cast( + &*conformance->getWitnessTablePattern())) { + // Fill in the provided part of the requirements from the pattern. + for (size_t i = 0, e = numPatternWitnesses; i < e; ++i) { + table[i] = pattern[i]; + } + } else { + // Put the conformance descriptor in place. Instantiation will fill in the + // rest. + assert(numPatternWitnesses == 0); + table[0] = (void *)conformance; } // Copy any instantiation arguments that correspond to conditional diff --git a/test/IRGen/newtype.swift b/test/IRGen/newtype.swift index 31fac5b62f6..03534215077 100644 --- a/test/IRGen/newtype.swift +++ b/test/IRGen/newtype.swift @@ -8,8 +8,8 @@ import Newtype // REQUIRES: objc_interop -// Witness table for synthesized ClosedEnums : _ObjectiveCBridgeable. -// CHECK: @"$sSo13SNTClosedEnumas21_ObjectiveCBridgeableSCWp" = linkonce_odr +// Conformance descriptor for synthesized ClosedEnums : _ObjectiveCBridgeable. +// CHECK: @"$sSo13SNTClosedEnumas21_ObjectiveCBridgeableSCMc" = // CHECK-LABEL: define swiftcc %TSo8NSStringC* @"$s7newtype14getErrorDomainSo08SNTErrorD0ayF"() public func getErrorDomain() -> ErrorDomain { diff --git a/test/IRGen/objc_extensions.swift b/test/IRGen/objc_extensions.swift index 0bd94589ce5..23279fa932d 100644 --- a/test/IRGen/objc_extensions.swift +++ b/test/IRGen/objc_extensions.swift @@ -180,7 +180,7 @@ extension NSDogcow { @NSManaged var woof: Int } -// CHECK: @"$sSo8NSObjectC15objc_extensionsE8SomeEnum33_1F05E59585E0BB585FCA206FBFF1A92DLLOSQACWp" = +// CHECK: @"$sSo8NSObjectC15objc_extensionsE8SomeEnum33_1F05E59585E0BB585FCA206FBFF1A92DLLOSQACMc" = class SwiftSubGizmo : SwiftBaseGizmo { diff --git a/test/IRGen/protocol_conformance_records.swift b/test/IRGen/protocol_conformance_records.swift index 984a5effa62..2b6bba38368 100644 --- a/test/IRGen/protocol_conformance_records.swift +++ b/test/IRGen/protocol_conformance_records.swift @@ -119,7 +119,7 @@ extension NativeGenericType : Spoon where T: Spoon { // -- nominal type descriptor // CHECK-SAME: @"{{got.|__imp_}}$sSiMn" // -- witness table pattern -// CHECK-SAME: @"$sSi18resilient_protocol22OtherResilientProtocol0B20_conformance_recordsWp" +// CHECK-SAME: i32 0, // -- flags // CHECK-SAME: i32 131144, // -- module context for retroactive conformance diff --git a/test/IRGen/protocol_resilience.sil b/test/IRGen/protocol_resilience.sil index 0f001098171..d4b8955a661 100644 --- a/test/IRGen/protocol_resilience.sil +++ b/test/IRGen/protocol_resilience.sil @@ -78,24 +78,15 @@ protocol InternalProtocol { func f() } -// Generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements +// No generic witness table pattern for ConformsWithRequirements : ProtocolWithRequirements; it's all resilient -// CHECK: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" = - -// CHECK-SAME: internal global [1 x i8*] [ - -// -- conformance descriptor -// CHECK-SAME: "$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAMc" - -// CHECK-SAME: ] +// CHECK-NOT: @"$s19protocol_resilience24ConformsWithRequirementsV010resilient_A008ProtocoldE0AAWp" = -// Witness table pattern for conformance with resilient associated type +// No witness table pattern for conformance with resilient associated type + +// CHECK-NOT: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal -// CHECK: @"$s19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AAWp" = {{(protected )?}}internal global [3 x i8*] [ -// CHECK-SAME: @"associated conformance 19protocol_resilience26ConformsWithResilientAssocVAA03HaseF0AA1TAaDP_010resilient_A005OtherE8Protocol" -// CHECK-SAME: @"symbolic 19protocol_resilience23ResilientConformingTypeV" -// CHECK-SAME: ] // Protocol conformance descriptor for ResilientConformingType : OtherResilientProtocol @@ -104,7 +95,7 @@ protocol InternalProtocol { // CHECK-SAME: i32 131072, // -- number of witness table entries -// CHECK-SAME: i16 1, +// CHECK-SAME: i16 0, // -- size of private area + 'requires instantiation' bit (not set) // CHECK-SAME: i16 0, @@ -134,7 +125,7 @@ protocol InternalProtocol { // CHECK-SAME: @secondWitness // -- number of witness table entries -// CHECK-SAME: i16 1, +// CHECK-SAME: i16 0, // -- size of private area + 'requires instantiation' bit (not set) // CHECK-SAME: i16 0, diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift index 77a26bb6d1f..e21e5c6306b 100644 --- a/test/IRGen/protocol_resilience_descriptors.swift +++ b/test/IRGen/protocol_resilience_descriptors.swift @@ -61,8 +61,9 @@ public struct Y { } // CHECK-USAGE-LABEL: @"$s31protocol_resilience_descriptors1YV010resilient_A022OtherResilientProtocolAAMc" = // CHECK-USAGE-SAME: i32 131072, -// CHECK-USAGE-SAME: i16 1, -// CHECK-USAGE-SAME: i16 0 +// CHECK-USAGE-SAME: i16 0, +// CHECK-USAGE-SAME: i16 0, +// CHECK-USAGE-SAME: i32 0 extension Y: OtherResilientProtocol { } // CHECK-USAGE: @"$s31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAMc" =