Skip to content

Commit 0185780

Browse files
authored
Merge pull request #42172 from nkcsgexi/spi-available-only-api-level-lib
Availability: only diagnose exposing SPI_AVAILABLE symbols in modules with library-level=API
2 parents 9e63351 + 6b1f736 commit 0185780

7 files changed

+58
-15
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,13 +1546,21 @@ swift::getDisallowedOriginKind(const Decl *decl,
15461546
// Implementation-only imported, cannot be reexported.
15471547
return DisallowedOriginKind::ImplementationOnly;
15481548
} else if ((decl->isSPI() || decl->isAvailableAsSPI()) && !where.isSPI()) {
1549-
// Allowing unavailable context to use @_spi_available decls.
1550-
// Decls with @_spi_available aren't hidden entirely from public interfaces,
1551-
// thus public interfaces may still refer them. Be forgiving here so public
1552-
// interfaces can compile.
1553-
if (where.getUnavailablePlatformKind().hasValue() &&
1554-
decl->isAvailableAsSPI() && !decl->isSPI()) {
1555-
return DisallowedOriginKind::None;
1549+
if (decl->isAvailableAsSPI() && !decl->isSPI()) {
1550+
// Allowing unavailable context to use @_spi_available decls.
1551+
// Decls with @_spi_available aren't hidden entirely from public interfaces,
1552+
// thus public interfaces may still refer them. Be forgiving here so public
1553+
// interfaces can compile.
1554+
if (where.getUnavailablePlatformKind().hasValue())
1555+
return DisallowedOriginKind::None;
1556+
// We should only diagnose SPI_AVAILABLE usage when the library level is API.
1557+
// Using SPI_AVAILABLE symbols in private frameworks or executable targets
1558+
// should be allowed.
1559+
if (auto *mod = where.getDeclContext()->getParentModule()) {
1560+
if (mod->getLibraryLevel() != LibraryLevel::API) {
1561+
return DisallowedOriginKind::None;
1562+
}
1563+
}
15561564
}
15571565
// SPI can only be exported in SPI.
15581566
return where.getDeclContext()->getParentModule() == M ?

test/ClangImporter/availability_spi_as_unavailable.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// REQUIRES: OS=macosx
2-
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING
3-
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify
2+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING -library-level api
3+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify -library-level api
44

55
#if NOT_UNDERLYING
66
import SPIContainer

test/ClangImporter/availability_spi_as_unavailable_bridging_header.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// REQUIRES: OS=macosx
2-
// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/frameworks/SPIContainer.framework/Headers/SPIContainer.h -verify
2+
// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/frameworks/SPIContainer.framework/Headers/SPIContainer.h -verify -library-level api
33

44

55
@_spi(a) public let a: SPIInterface1
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// REQUIRES: OS=macosx
2+
3+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING
4+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING -library-level spi
5+
6+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify
7+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify -library-level spi
8+
9+
10+
#if NOT_UNDERLYING
11+
import SPIContainer
12+
#endif
13+
14+
@_spi(a) public let a: SPIInterface1
15+
@_spi(a) public let b: SPIInterface2
16+
17+
public let c: SPIInterface1
18+
public let d: SPIInterface2
19+
20+
@inlinable
21+
public func inlinableUsingSPI() {
22+
SharedInterface.foo()
23+
}
24+
25+
@available(macOS, unavailable)
26+
public let e: SPIInterface2
27+
28+
@available(iOS, unavailable)
29+
public let f: SPIInterface2
30+
31+
@inlinable
32+
@available(macOS, unavailable)
33+
public func inlinableUnavailableUsingSPI() {
34+
SharedInterface.foo()
35+
}

test/ClangImporter/availability_spi_transitive.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// REQUIRES: OS=macosx
2-
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify
2+
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -library-level api
33

44
import SPIContainerImporter
55

test/ModuleInterface/spi-available-interface.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// REQUIRES: OS=macosx
22
// RUN: %empty-directory(%t/inputs)
3-
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -DFoo -emit-module-interface-path %t/inputs/Foo.swiftinterface -module-name Foo -enable-library-evolution -disable-clang-spi
3+
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -DFoo -emit-module-interface-path %t/inputs/Foo.swiftinterface -module-name Foo -enable-library-evolution -disable-clang-spi -library-level api
44

5-
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -enable-library-evolution -I %t/inputs -disable-clang-spi
5+
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -enable-library-evolution -I %t/inputs -disable-clang-spi -library-level api
66

7-
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/inputs/Foo.swiftinterface -F %S/../ClangImporter/Inputs/frameworks -disable-clang-spi
7+
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/inputs/Foo.swiftinterface -F %S/../ClangImporter/Inputs/frameworks -disable-clang-spi -library-level api
88

99

1010
#if Foo

test/Sema/spi-available-inline.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// REQUIRES: VENDOR=apple
22
// REQUIRES: OS=macosx
3-
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx11.9
3+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx11.9 -library-level api
44

55
@_spi_available(macOS 10.4, *)
66
public class MacOSSPIClass { public init() {} }

0 commit comments

Comments
 (0)