Skip to content

Commit 1757061

Browse files
committed
[Serialization] Allow loading modules built on some SDK variants
When restricting loading swiftmodules to the SDK used to build them, an exception should be made for modules built against an SDK that is a subset of the SDK used when loading the module. In such a case, the swiftmodule file is more reliable. rdar://92827584
1 parent 2266a57 commit 1757061

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

lib/Serialization/ModuleFile.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,18 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
156156
return error(status);
157157
}
158158

159+
// The loaded module was built with a compatible SDK if either:
160+
// * it was the same SDK
161+
// * or one who's name is a prefix of the clients' SDK name. This expects
162+
// that a module built with macOS11 can be used with the macOS11.secret SDK.
163+
// This is generally the case as SDKs with suffixes are a superset of the
164+
// short SDK name equivalent. While this is accepted, this is still not a
165+
// recommended configuration and may lead to unreadable swiftmodules.
159166
StringRef moduleSDK = Core->SDKName;
160167
StringRef clientSDK = ctx.LangOpts.SDKName;
161168
if (ctx.SearchPathOpts.EnableSameSDKCheck &&
162169
!moduleSDK.empty() && !clientSDK.empty() &&
163-
moduleSDK != clientSDK) {
170+
!clientSDK.startswith(moduleSDK)) {
164171
status = Status::SDKMismatch;
165172
return error(status);
166173
}

test/Serialization/restrict-swiftmodule-to-sdk.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@
99
// RUN: %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name A -I %t/build -parse-stdlib -module-cache-path %t/cache
1010

1111
/// Build Client against SDK B, this should fail at loading Lib against a different SDK than A.
12-
// RUN: not %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name B -I %t/build -parse-stdlib -module-cache-path %t/cache 2>&1 | %FileCheck %s
13-
// CHECK: cannot load module 'Lib' built with SDK 'A' when using SDK 'B': {{.*}}Lib.swiftmodule
12+
// RUN: not %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name B -I %t/build -parse-stdlib -module-cache-path %t/cache 2>&1 | %FileCheck %s -check-prefix=CHECK-AvsB
13+
// CHECK-AvsB: cannot load module 'Lib' built with SDK 'A' when using SDK 'B': {{.*}}Lib.swiftmodule
14+
15+
/// Build Client against SDK A.Secret, this should accept the SDK as being a super set of A.
16+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name A.Secret -I %t/build -parse-stdlib -module-cache-path %t/cache
17+
18+
/// Build Lib against SDK C.Secret and Client against SDK C, this should be rejected.
19+
// RUN: %target-swift-frontend -emit-module %t/Lib.swift -swift-version 5 -target-sdk-name C.Secret -o %t/build -parse-stdlib -module-cache-path %t/cache
20+
// RUN: not %target-swift-frontend -typecheck %t/Client.swift -swift-version 5 -target-sdk-name C -I %t/build -parse-stdlib -module-cache-path %t/cache 2>&1 | %FileCheck %s -check-prefix=CHECK-C
21+
// CHECK-C: cannot load module 'Lib' built with SDK 'C.Secret' when using SDK 'C': {{.*}}Lib.swiftmodule
1422

1523
// BEGIN Lib.swift
1624
public func foo() {}

0 commit comments

Comments
 (0)