Skip to content

Commit efc5c55

Browse files
committed
Serialization: Handle possibly-null serialized xrefs for optional protocol witnesses.
Fixes SR-4850 | rdar://problem/32134722.
1 parent deef5ff commit efc5c55

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4590,7 +4590,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
45904590

45914591
auto deserializedReq = getDeclChecked(*rawIDIter++);
45924592
if (deserializedReq) {
4593-
req = cast<ValueDecl>(*deserializedReq);
4593+
req = cast_or_null<ValueDecl>(*deserializedReq);
45944594
} else if (getContext().LangOpts.EnableDeserializationRecovery) {
45954595
consumeError(deserializedReq.takeError());
45964596
req = nullptr;
@@ -4603,7 +4603,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
46034603
ValueDecl *witness;
46044604
auto deserializedWitness = getDeclChecked(*rawIDIter++);
46054605
if (deserializedWitness) {
4606-
witness = cast<ValueDecl>(*deserializedWitness);
4606+
witness = cast_or_null<ValueDecl>(*deserializedWitness);
46074607
// Across language compatibility versions, the witnessing decl may have
46084608
// changed its signature as seen by the current compatibility version.
46094609
// In that case, we want the conformance to still be available, but
@@ -4705,7 +4705,8 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
47054705
auto first = cast<AssociatedTypeDecl>(getDecl(*rawIDIter++));
47064706
auto second = getType(*rawIDIter++);
47074707
auto third = cast_or_null<TypeDecl>(getDecl(*rawIDIter++));
4708-
if (isa<TypeAliasDecl>(third) &&
4708+
if (third &&
4709+
isa<TypeAliasDecl>(third) &&
47094710
third->getModuleContext() != getAssociatedModule() &&
47104711
!third->getDeclaredInterfaceType()->isEqual(second)) {
47114712
// Conservatively drop references to typealiases in other modules
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
@import Foundation;
2+
3+
@interface ObjCFoo: NSObject
4+
@end
5+
6+
@protocol ObjCProto <NSObject>
7+
8+
- (void)nonoptionalMethod;
9+
10+
@optional
11+
- (void)optionalMethod;
12+
13+
@required
14+
- (void)nonoptionalMethod2;
15+
16+
@end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
public struct Bar<T: SwiftProto> {}
3+
public struct Baz {
4+
var bar: Bar<Foo>
5+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -c -emit-module-path %t/cross_module_optional_protocol_reqt~partial.swiftmodule -primary-file %s %S/Inputs/cross_module_optional_protocol_reqt_2.swift -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h -o /dev/null
3+
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -c -emit-module-path %t/cross_module_optional_protocol_reqt_2~partial.swiftmodule %s -primary-file %S/Inputs/cross_module_optional_protocol_reqt_2.swift -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h -o /dev/null
4+
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -emit-module -emit-module-path %t/cross_module_optional_protocol_reqt.swiftmodule %t/cross_module_optional_protocol_reqt~partial.swiftmodule %t/cross_module_optional_protocol_reqt_2~partial.swiftmodule -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h
5+
// REQUIRES: objc_interop
6+
7+
public protocol SwiftProto: ObjCProto {}
8+
9+
public class Foo: ObjCFoo, SwiftProto {
10+
public func nonoptionalMethod() {}
11+
public func nonoptionalMethod2() {}
12+
}

0 commit comments

Comments
 (0)