Skip to content

Commit 6328fe3

Browse files
authored
Merge pull request #34912 from xymus/warn-ineffective-spi-import
[Sema] Warn on @_spi imports of modules built from their public interface
2 parents 820b2c6 + 05534f1 commit 6328fe3

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,10 @@ ERROR(spi_attribute_on_protocol_requirement,none,
17881788
ERROR(spi_attribute_on_frozen_stored_properties,none,
17891789
"stored property %0 cannot be declared '@_spi' in a '@frozen' struct",
17901790
(DeclName))
1791+
WARNING(spi_attribute_on_import_of_public_module,none,
1792+
"'@_spi' import of %0 will not include any SPI symbols; "
1793+
"%0 was built from the public interface at %1",
1794+
(DeclName, StringRef))
17911795

17921796
// Opaque return types
17931797
ERROR(opaque_type_invalid_constraint,none,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,21 @@ void AttributeChecker::visitSPIAccessControlAttr(SPIAccessControlAttr *attr) {
10301030
}
10311031
}
10321032
}
1033+
1034+
if (auto ID = dyn_cast<ImportDecl>(D)) {
1035+
auto importedModule = ID->getModule();
1036+
if (importedModule) {
1037+
auto path = importedModule->getModuleFilename();
1038+
if (llvm::sys::path::extension(path) == ".swiftinterface" &&
1039+
!path.endswith(".private.swiftinterface")) {
1040+
// If the module was built from the public swiftinterface, it can't
1041+
// have any SPI.
1042+
diagnose(attr->getLocation(),
1043+
diag::spi_attribute_on_import_of_public_module,
1044+
importedModule->getName(), path);
1045+
}
1046+
}
1047+
}
10331048
}
10341049

10351050
static bool checkObjCDeclContext(Decl *D) {

test/SPI/experimental_spi_imports_type_check.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
// RUN: %target-typecheck-verify-swift -DCLIENT -I %t
1717
// RUN: %target-swift-frontend -typecheck %s -DCLIENT -DCLIENT_LOAD_CORE -I %t
1818

19-
/// Test with the public swiftinterface file, the SPI is unknown.
20-
// RUN: rm %t/LibPublic.private.swiftinterface
21-
// RUN: %target-typecheck-verify-swift -DCLIENT -I %t
22-
// RUN: %target-typecheck-verify-swift -DCLIENT -DCLIENT_LOAD_CORE -I %t
23-
2419
#if LIB_CORE
2520

2621
public struct CoreStruct {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// Test the warning on an SPI import of the public interface of a module.
2+
3+
// RUN: %empty-directory(%t)
4+
5+
/// Compile the SPI lib.
6+
// RUN: %target-swift-frontend -enable-experimental-prespecialization -emit-module %S/Inputs/spi_helper.swift -module-name SPIHelper -emit-module-path %t/SPIHelper.swiftmodule -emit-module-interface-path %t/SPIHelper.swiftinterface -emit-private-module-interface-path %t/SPIHelper.private.swiftinterface -enable-library-evolution -swift-version 5 -parse-as-library
7+
8+
/// Reading from swiftmodule, no warning.
9+
// RUN: %target-swift-frontend -typecheck %s -I %t
10+
11+
/// Reading from .private.swiftinterface, no warning.
12+
// RUN: rm %t/SPIHelper.swiftmodule
13+
// RUN: %target-swift-frontend -typecheck %s -I %t
14+
15+
/// Reading from the public .swiftinterface should produce the warning.
16+
// RUN: rm %t/SPIHelper.private.swiftinterface
17+
// RUN: %target-typecheck-verify-swift -I %t
18+
19+
@_spi(SPIHelper) import SPIHelper // expected-warning {{'@_spi' import of 'SPIHelper' will not include any SPI symbols; 'SPIHelper' was built from the public interface at}}

0 commit comments

Comments
 (0)