mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
cross-module-optimization: Don't serialize functions which reference implementationOnly-imported functions
The check for implementationOnly imports was already done for types, but it was missing for functions. Fixes a crash when implementationOnly-importing a C module. https://bugs.swift.org/browse/SR-15048 rdar://81701218
This commit is contained in:
@@ -676,9 +676,10 @@ public:
|
||||
/// This assumes that \p module was imported.
|
||||
bool isImportedImplementationOnly(const ModuleDecl *module) const;
|
||||
|
||||
/// Returns true if a function, which is using \p nominal, can be serialized
|
||||
/// by cross-module-optimization.
|
||||
bool canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const;
|
||||
/// Returns true if decl context or its content can be serialized by
|
||||
/// cross-module-optimization.
|
||||
/// The \p ctxt can e.g. be a NominalType or the context of a function.
|
||||
bool canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const;
|
||||
|
||||
/// Finds all top-level decls of this module.
|
||||
///
|
||||
|
||||
@@ -2353,14 +2353,15 @@ bool ModuleDecl::isImportedImplementationOnly(const ModuleDecl *module) const {
|
||||
}
|
||||
|
||||
bool ModuleDecl::
|
||||
canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const {
|
||||
ModuleDecl *moduleOfNominal = nominal->getParentModule();
|
||||
canBeUsedForCrossModuleOptimization(DeclContext *ctxt) const {
|
||||
ModuleDecl *moduleOfCtxt = ctxt->getParentModule();
|
||||
|
||||
// If the nominal is defined in the same module, it's fine.
|
||||
if (moduleOfNominal == this)
|
||||
// If the context defined in the same module - or is the same module, it's
|
||||
// fine.
|
||||
if (moduleOfCtxt == this)
|
||||
return true;
|
||||
|
||||
// See if nominal is imported in a "regular" way, i.e. not with
|
||||
// See if context is imported in a "regular" way, i.e. not with
|
||||
// @_implementationOnly or @_spi.
|
||||
ModuleDecl::ImportFilter filter = {
|
||||
ModuleDecl::ImportFilterKind::Exported,
|
||||
@@ -2370,7 +2371,7 @@ canBeUsedForCrossModuleOptimization(NominalTypeDecl *nominal) const {
|
||||
|
||||
auto &imports = getASTContext().getImportCache();
|
||||
for (auto &desc : results) {
|
||||
if (imports.isImportedBy(moduleOfNominal, desc.importedModule))
|
||||
if (imports.isImportedBy(moduleOfCtxt, desc.importedModule))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -386,6 +386,11 @@ bool CrossModuleSerializationSetup::canUseFromInline(SILFunction *func,
|
||||
if (!func)
|
||||
return false;
|
||||
|
||||
if (DeclContext *funcCtxt = func->getDeclContext()) {
|
||||
if (!M.getSwiftModule()->canBeUsedForCrossModuleOptimization(funcCtxt))
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (func->getLinkage()) {
|
||||
case SILLinkage::PublicNonABI:
|
||||
return func->isSerialized() != IsNotSerialized;
|
||||
|
||||
7
test/SILOptimizer/Inputs/cross-module/c-module.c
Normal file
7
test/SILOptimizer/Inputs/cross-module/c-module.c
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#include "c-module.h"
|
||||
|
||||
long privateCFunc() {
|
||||
return 123;
|
||||
}
|
||||
|
||||
3
test/SILOptimizer/Inputs/cross-module/c-module.h
Normal file
3
test/SILOptimizer/Inputs/cross-module/c-module.h
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
long privateCFunc();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Submodule
|
||||
@_implementationOnly import PrivateSubmodule
|
||||
@_implementationOnly import PrivateCModule
|
||||
|
||||
private enum PE<T> {
|
||||
case A
|
||||
@@ -268,11 +269,19 @@ public func callUnrelated<T>(_ t: T) -> T {
|
||||
return t
|
||||
}
|
||||
|
||||
public func callImplementationOnly<T>(_ t: T) -> T {
|
||||
public func callImplementationOnlyType<T>(_ t: T) -> T {
|
||||
let p = PrivateStr(i: 27)
|
||||
print(p.test())
|
||||
return t
|
||||
}
|
||||
|
||||
public func callImplementationOnlyFunc<T>(_ t: T) -> Int {
|
||||
return privateFunc()
|
||||
}
|
||||
|
||||
public func callCImplementationOnly<T>(_ t: T) -> Int {
|
||||
return Int(privateCFunc())
|
||||
}
|
||||
|
||||
|
||||
public let globalLet = 529387
|
||||
@@ -12,3 +12,6 @@ public struct PrivateStr {
|
||||
}
|
||||
}
|
||||
|
||||
public func privateFunc() -> Int {
|
||||
return 40
|
||||
}
|
||||
3
test/SILOptimizer/Inputs/cross-module/module.modulemap
Normal file
3
test/SILOptimizer/Inputs/cross-module/module.modulemap
Normal file
@@ -0,0 +1,3 @@
|
||||
module PrivateCModule {
|
||||
header "c-module.h"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// First test: functional correctness
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Test.swiftmodule -module-name=Test -I%t %S/Inputs/cross-module-objc.swift -c -o %t/test.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Test.swiftmodule -module-name=Test -I%t %S/Inputs/cross-module/cross-module-objc.swift -c -o %t/test.o
|
||||
// RUN: %target-build-swift -O -wmo -module-name=Main -I%t %s -c -o %t/main.o
|
||||
// RUN: %target-swiftc_driver %t/main.o %t/test.o -o %t/a.out
|
||||
// RUN: %target-codesign %t/a.out
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
// First test: functional correctness
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Submodule.swiftmodule -module-name=Submodule %S/Inputs/cross-submodule.swift -c -o %t/submodule.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/PrivateSubmodule.swiftmodule -module-name=PrivateSubmodule %S/Inputs/cross-private-submodule.swift -c -o %t/privatesubmodule.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Test.swiftmodule -module-name=Test -I%t %S/Inputs/cross-module.swift -c -o %t/test.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Submodule.swiftmodule -module-name=Submodule %S/Inputs/cross-module/cross-submodule.swift -c -o %t/submodule.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/PrivateSubmodule.swiftmodule -module-name=PrivateSubmodule %S/Inputs/cross-module/cross-private-submodule.swift -c -o %t/privatesubmodule.o
|
||||
// RUN: %target-clang -c --language=c %S/Inputs/cross-module/c-module.c -o %t/c-module.o
|
||||
// RUN: %target-build-swift -O -wmo -parse-as-library -cross-module-optimization -emit-module -emit-module-path=%t/Test.swiftmodule -module-name=Test -I%t -I%S/Inputs/cross-module %S/Inputs/cross-module/cross-module.swift -c -o %t/test.o
|
||||
// RUN: %target-build-swift -O -wmo -module-name=Main -I%t %s -c -o %t/main.o
|
||||
// RUN: %target-swiftc_driver %t/main.o %t/test.o %t/submodule.o %t/privatesubmodule.o -o %t/a.out
|
||||
// RUN: %target-swiftc_driver %t/main.o %t/test.o %t/submodule.o %t/privatesubmodule.o %t/c-module.o -o %t/a.out
|
||||
// RUN: %target-codesign %t/a.out
|
||||
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
|
||||
|
||||
// Check if it also works if the main module is compiled with -Onone:
|
||||
|
||||
// RUN: %target-build-swift -Onone -wmo -module-name=Main -I%t %s -c -o %t/main-onone.o
|
||||
// RUN: %target-swiftc_driver %t/main-onone.o %t/test.o %t/submodule.o %t/privatesubmodule.o -o %t/a.out
|
||||
// RUN: %target-swiftc_driver %t/main-onone.o %t/test.o %t/submodule.o %t/privatesubmodule.o %t/c-module.o -o %t/a.out
|
||||
// RUN: %target-codesign %t/a.out
|
||||
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
|
||||
|
||||
@@ -146,8 +147,14 @@ func testGlobal() {
|
||||
@inline(never)
|
||||
func testImplementationOnly() {
|
||||
// CHECK-OUTPUT: 27
|
||||
// CHECK-SIL2: function_ref @$s4Test22callImplementationOnlyyxxlF
|
||||
print(callImplementationOnly(27))
|
||||
// CHECK-SIL2: function_ref @$s4Test26callImplementationOnlyTypeyxxlF
|
||||
print(callImplementationOnlyType(27))
|
||||
// CHECK-OUTPUT: 40
|
||||
// CHECK-SIL2: function_ref @$s4Test26callImplementationOnlyFuncySixlF
|
||||
print(callImplementationOnlyFunc(0))
|
||||
// CHECK-OUTPUT: 123
|
||||
// CHECK-SIL2: function_ref @$s4Test23callCImplementationOnlyySixlF
|
||||
print(callCImplementationOnly(0))
|
||||
// CHECK-SIL2: } // end sil function '$s4Main22testImplementationOnlyyyF'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user