Skip to content

Commit cd32aae

Browse files
committed
Sema: exempt some imports from the warning on ioi use from non-resilient module
The correct use @_implementationOnly from a non-resilient module is not enforced by the compiler at this time. Using that configuration can cause memory corruption at runtime if it affects the memory layout of types, and it can lead to compiler crashes at compilation in general. Some modules rely on this configuration with a very limited use for it. We can grandfather them in its use and silence the warning on specific import edges.
1 parent 2752414 commit cd32aae

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

lib/Sema/ImportResolution.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -779,16 +779,29 @@ void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
779779
if (topLevelModule.get() == ctx.TheBuiltinModule)
780780
return;
781781

782+
Identifier importerName = SF.getParentModule()->getName(),
783+
targetName = topLevelModule.get()->getName();
784+
782785
// @_implementationOnly is only supported when used from modules built with
783786
// library-evolution. Otherwise it can lead to runtime crashes from a lack
784787
// of memory layout information when building clients unaware of the
785788
// dependency. The missing information is provided at run time by resilient
786789
// modules.
790+
// We exempt some imports using @_implementationOnly in a safe way from
791+
// packages that cannot be resilient.
787792
if (import.options.contains(ImportFlags::ImplementationOnly) &&
788-
!SF.getParentModule()->isResilient() && topLevelModule) {
793+
!SF.getParentModule()->isResilient() && topLevelModule &&
794+
!(((targetName.str() == "CCryptoBoringSSL" ||
795+
targetName.str() == "CCryptoBoringSSLShims") &&
796+
(importerName.str() == "Crypto" ||
797+
importerName.str() == "_CryptoExtras" ||
798+
importerName.str() == "CryptoBoringWrapper")) ||
799+
((targetName.str() == "CNIOBoringSSL" ||
800+
targetName.str() == "CNIOBoringSSLShims") &&
801+
importerName.str() == "NIOSSL"))) {
789802
ctx.Diags.diagnose(import.importLoc,
790803
diag::implementation_only_requires_library_evolution,
791-
SF.getParentModule()->getName());
804+
importerName);
792805
}
793806

794807
if (import.options.contains(ImportFlags::ImplementationOnly) ||
@@ -801,8 +814,7 @@ void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
801814

802815
auto inFlight = ctx.Diags.diagnose(import.module.getModulePath().front().Loc,
803816
diag::module_not_compiled_with_library_evolution,
804-
topLevelModule.get()->getName(),
805-
SF.getParentModule()->getName());
817+
targetName, importerName);
806818

807819
if (ctx.LangOpts.hasFeature(Feature::InternalImportsByDefault)) {
808820
// This will catch Swift 6 language mode as well where

test/Sema/implementation-only-import-from-non-resilient.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@
1212
// RUN: %target-swift-frontend -typecheck %t/client-resilient.swift -I %t -verify \
1313
// RUN: -enable-library-evolution -swift-version 5
1414

15+
/// Some imports are exempt.
16+
// RUN: %target-swift-frontend -emit-module %t/empty.swift \
17+
// RUN: -o %t/CCryptoBoringSSL.swiftmodule \
18+
// RUN: -enable-library-evolution -swift-version 5
19+
// RUN: %target-swift-frontend -typecheck %t/Crypto.swift -I %t -verify \
20+
// RUN: -module-name Crypto
21+
1522
//--- empty.swift
1623

1724
//--- client-non-resilient.swift
@@ -21,3 +28,8 @@ import B
2128
//--- client-resilient.swift
2229
@_implementationOnly import A
2330
import B
31+
32+
//--- Crypto.swift
33+
@_implementationOnly import A // expected-warning {{using '@_implementationOnly' without enabling library evolution for 'Crypto' may lead to instability during execution}}
34+
import B
35+
@_implementationOnly import CCryptoBoringSSL

0 commit comments

Comments
 (0)