Skip to content

Commit 9e91f4e

Browse files
authored
Merge pull request #68205 from tshortli/conformance-deserialization-safety-refinement
Serialization: Refine safety checks for extensions/protocols
2 parents ccbb6e1 + 4622873 commit 9e91f4e

File tree

4 files changed

+24
-24
lines changed

4 files changed

+24
-24
lines changed

lib/Serialization/Serialization.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3289,9 +3289,10 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
32893289

32903290
// We can mark the extension unsafe only if it has no public
32913291
// conformances.
3292-
auto protocols = ext->getLocalProtocols(
3293-
ConformanceLookupKind::OnlyExplicit);
3294-
if (!protocols.empty())
3292+
auto protocols = ext->getLocalProtocols(ConformanceLookupKind::All);
3293+
bool hasSafeConformances = std::any_of(protocols.begin(), protocols.end(),
3294+
isDeserializationSafe);
3295+
if (hasSafeConformances)
32953296
return true;
32963297

32973298
// Truly empty extensions are safe, it may happen in swiftinterfaces.
@@ -3301,9 +3302,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
33013302
return false;
33023303
}
33033304

3304-
if (isa<ProtocolDecl>(decl))
3305-
return true;
3306-
33073305
auto value = cast<ValueDecl>(decl);
33083306

33093307
// A decl is safe if formally accessible publicly.

test/Serialization/Safety/indirect-conformance.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@
1212

1313
// RUN: cat %t/Lib.swiftinterface | %FileCheck %t/Lib.swift
1414

15-
public protocol PublicProtocol : AnyObject {}
16-
// CHECK: public protocol PublicProtocol : AnyObject
15+
public protocol PublicProtocol {}
16+
// CHECK: public protocol PublicProtocol
1717

1818
protocol InternalProtocol: PublicProtocol {}
1919
// CHECK-NOT: InternalProtocol
2020

2121
public class IndirectConformant {
2222
public init() {}
2323
}
24+
2425
extension IndirectConformant: InternalProtocol {}
2526
// CHECK: extension Lib.IndirectConformant : Lib.PublicProtocol {}
2627

28+
extension String: InternalProtocol {}
29+
// CHECK: extension Swift.String : Lib.PublicProtocol {}
30+
2731
//--- Client.swift
2832

2933
/// Works without safety.
@@ -43,10 +47,8 @@ import Lib
4347

4448
func requireConformanceToPublicProtocol(_ a: PublicProtocol) {}
4549
requireConformanceToPublicProtocol(IndirectConformant())
50+
requireConformanceToPublicProtocol("string")
4651

47-
/// Deserialization safety should keep the original chain. We're mostly
48-
/// documenting the current safety implementation details here, if we can get
49-
/// without deserializing 'InternalProtocol' it would be even better.
5052
// CHECK: Deserialized: 'IndirectConformant'
5153
// CHECK: Deserialized: 'PublicProtocol'
52-
// CHECK: Deserialized: 'InternalProtocol'
54+
// CHECK-NOT: Deserialized: 'InternalProtocol'

test/Serialization/Safety/unsafe-decls.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434
public protocol PublicProto {}
3535
// SAFETY-PRIVATE: Serialization safety, safe: 'PublicProto'
3636
internal protocol InternalProto {}
37-
// SAFETY-INTERNAL: Serialization safety, safe: 'InternalProto'
38-
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'InternalProto'
37+
// SAFETY-INTERNAL: Serialization safety, unsafe: 'InternalProto'
38+
// NO-SAFETY-INTERNAL: Serialization safety, unsafe: 'InternalProto'
3939
private protocol PrivateProto {}
40-
// SAFETY-PRIVATE: Serialization safety, safe: 'PrivateProto'
40+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'PrivateProto'
4141
fileprivate protocol FileprivateProto {}
42-
// SAFETY-PRIVATE: Serialization safety, safe: 'FileprivateProto'
42+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'FileprivateProto'
4343

4444
internal struct InternalStruct : PublicProto {
4545
// SAFETY-INTERNAL: Serialization safety, unsafe: 'InternalStruct'

test/Serialization/Safety/unsafe-extensions.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ extension ExtendedPublic : PublicProto {
4747

4848
/// Internal
4949
internal protocol InternalProto {}
50-
// SAFETY-INTERNAL: Serialization safety, safe: 'InternalProto'
51-
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'InternalProto'
50+
// SAFETY-INTERNAL: Serialization safety, unsafe: 'InternalProto'
51+
// NO-SAFETY-INTERNAL: Serialization safety, unsafe: 'InternalProto'
5252
internal struct ExtendedInternal {}
5353
// SAFETY-INTERNAL: Serialization safety, unsafe: 'ExtendedInternal'
5454
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'ExtendedInternal'
@@ -63,7 +63,7 @@ extension ExtendedInternal : InternalProto {}
6363

6464
/// Private
6565
private protocol PrivateProto {}
66-
// SAFETY-PRIVATE: Serialization safety, safe: 'PrivateProto'
66+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'PrivateProto'
6767
private struct ExtendedPrivate {}
6868
// SAFETY-PRIVATE: Serialization safety, unsafe: 'ExtendedPrivate'
6969
extension ExtendedPrivate {
@@ -75,7 +75,7 @@ extension ExtendedPrivate : PrivateProto {}
7575

7676
/// Fileprivate
7777
private protocol FileprivateProto {}
78-
// SAFETY-PRIVATE: Serialization safety, safe: 'FileprivateProto'
78+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'FileprivateProto'
7979
private struct ExtendedFileprivate {}
8080
// SAFETY-PRIVATE: Serialization safety, unsafe: 'ExtendedFileprivate'
8181
extension ExtendedFileprivate {
@@ -87,14 +87,14 @@ extension ExtendedFileprivate : FileprivateProto {}
8787

8888
/// Back to public
8989
extension ExtendedPublic : InternalProto {
90-
// SAFETY-INTERNAL: Serialization safety, safe: 'extension ExtendedPublic'
91-
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'extension ExtendedPublic'
90+
// SAFETY-INTERNAL: Serialization safety, unsafe: 'extension ExtendedPublic'
91+
// NO-SAFETY-INTERNAL: Serialization safety, unsafe: 'extension ExtendedPublic'
9292
}
9393
extension ExtendedPublic : PrivateProto {
94-
// SAFETY-PRIVATE: Serialization safety, safe: 'extension ExtendedPublic'
94+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'extension ExtendedPublic'
9595
}
9696
extension ExtendedPublic : FileprivateProto {
97-
// SAFETY-PRIVATE: Serialization safety, safe: 'extension ExtendedPublic'
97+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'extension ExtendedPublic'
9898
}
9999

100100
extension ExtendedPublic {

0 commit comments

Comments
 (0)