Skip to content

Commit e0e02f5

Browse files
committed
[Serialization] Evaluate the safety of opaque types
Some compilation paths access the opaque return type type by itself without going through its function. So access to the type must be protected, otherwise deserialization fails at getting the naming decl when it's unsafe. rdar://105085860
1 parent dc1b73f commit e0e02f5

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

lib/Serialization/Serialization.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,7 +3192,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
31923192
// Note: There's likely room to report some of these as unsafe to prevent
31933193
// failures.
31943194
if (isa<GenericTypeParamDecl>(decl) ||
3195-
isa<OpaqueTypeDecl>(decl) ||
31963195
isa<ParamDecl>(decl) ||
31973196
isa<EnumCaseDecl>(decl) ||
31983197
isa<EnumElementDecl>(decl))
@@ -3215,7 +3214,10 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
32153214
// Write a human readable name to an identifier.
32163215
SmallString<64> out;
32173216
llvm::raw_svector_ostream outStream(out);
3218-
if (auto val = dyn_cast<ValueDecl>(decl)) {
3217+
if (auto opaque = dyn_cast<OpaqueTypeDecl>(decl)) {
3218+
outStream << "opaque ";
3219+
outStream << opaque->getOpaqueReturnTypeIdentifier();
3220+
} else if (auto val = dyn_cast<ValueDecl>(decl)) {
32193221
outStream << val->getName();
32203222
} else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
32213223
outStream << "extension ";

test/Serialization/Safety/skip-reading-internal-details.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public struct HiddenStruct {
6060

6161
@_implementationOnly import HiddenLib
6262

63+
public protocol Proto {}
64+
internal struct Struct : Proto {}
65+
6366
public struct PublicStruct {
6467
public init() {}
6568

@@ -71,6 +74,10 @@ public struct PublicStruct {
7174
internal func refToIOI() -> HiddenStruct {
7275
return HiddenStruct();
7376
}
77+
78+
internal func opaqueFunc() -> some Proto {
79+
return Struct()
80+
}
7481
}
7582

7683
//--- Client.swift

test/Serialization/Safety/unsafe-decls.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %target-swift-frontend -emit-module %s \
66
// RUN: -enable-library-evolution -swift-version 5 \
7-
// RUN: -Xllvm -debug-only=Serialization 2>&1 \
7+
// RUN: -Xllvm -debug-only=Serialization 2>&1 | %swift-demangle --simplified \
88
// RUN: | %FileCheck --check-prefixes=SAFETY-PRIVATE,SAFETY-INTERNAL %s
99

1010
// RUN: %target-swift-frontend -emit-module %s \
@@ -53,6 +53,9 @@ public struct PublicStruct {
5353
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'internalTypealias'
5454
// SAFETY-PRIVATE: Serialization safety, safe: 'localTypealias'
5555

56+
// SAFETY-PRIVATE: Serialization safety, safe: 'opaque PublicStruct.opaqueTypeFunc()'
57+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'opaque PublicStruct.opaqueFuncInternal()'
58+
5659
public init(publicInit a: Int) {}
5760
// SAFETY-PRIVATE: Serialization safety, safe: 'init(publicInit:)'
5861
internal init(internalInit a: Int) {}
@@ -69,11 +72,19 @@ public struct PublicStruct {
6972
// SAFETY-PRIVATE: Serialization safety, safe: 'inlinableFunc()'
7073
public func publicFunc() {}
7174
// SAFETY-PRIVATE: Serialization safety, safe: 'publicFunc()'
72-
@available(SwiftStdlib 5.1, *) // for the `some` keyword.
75+
76+
@available(SwiftStdlib 5.1, *) // for the `some` keyword.
7377
public func opaqueTypeFunc() -> some PublicProto {
78+
// SAFETY-PRIVATE: Serialization safety, safe: 'opaqueTypeFunc()'
7479
return InternalStruct()
7580
}
76-
// SAFETY-PRIVATE: Serialization safety, safe: 'opaqueTypeFunc()'
81+
82+
@available(SwiftStdlib 5.1, *) // for the `some` keyword.
83+
internal func opaqueFuncInternal() -> some PublicProto {
84+
// SAFETY-PRIVATE: Serialization safety, unsafe: 'opaqueFuncInternal()'
85+
return InternalStruct()
86+
}
87+
7788
internal func internalFunc() {}
7889
// SAFETY-INTERNAL: Serialization safety, unsafe: 'internalFunc()'
7990
// NO-SAFETY-INTERNAL: Serialization safety, safe: 'internalFunc()'

0 commit comments

Comments
 (0)