Skip to content

Commit d93ab20

Browse files
committed
CrossModuleOptimization: public global variables must not be serialized if they reference private functions/closures
For example: ``` public static var privateFunctionPointer: (Int) -> (Int) = { $0 } ``` Fixes a verifier crash and/or undefined symbol error rdar://99493254
1 parent 6c313ab commit d93ab20

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

lib/SILOptimizer/IPO/CrossModuleOptimization.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,16 @@ bool CrossModuleOptimization::canSerializeGlobal(SILGlobalVariable *global) {
313313
for (const SILInstruction &initInst : *global) {
314314
if (auto *FRI = dyn_cast<FunctionRefInst>(&initInst)) {
315315
SILFunction *referencedFunc = FRI->getReferencedFunction();
316+
317+
// In conservative mode we don't want to turn non-public functions into
318+
// public functions, because that can increase code size. E.g. if the
319+
// function is completely inlined afterwards.
320+
// Also, when emitting TBD files, we cannot introduce a new public symbol.
321+
if ((conservative || M.getOptions().emitTBD) &&
322+
!hasPublicVisibility(referencedFunc->getLinkage())) {
323+
return false;
324+
}
325+
316326
if (!canUseFromInline(referencedFunc))
317327
return false;
318328
}

lib/Serialization/SerializeSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,6 +2557,10 @@ void SILSerializer::writeSILGlobalVar(const SILGlobalVariable &g) {
25572557
(unsigned)g.isLet(),
25582558
TyID, dID);
25592559

2560+
// Don't emit the initializer instructions if not marked as "serialized".
2561+
if (!g.isSerialized())
2562+
return;
2563+
25602564
ValueIDs.clear();
25612565
InstID = 0;
25622566
unsigned ValueID = 2;

test/SILOptimizer/Inputs/cross-module/default-module.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ public func moduleKlassMember() -> Int {
2727
return k.i
2828
}
2929

30+
public struct ModuleStruct {
31+
public static var publicFunctionPointer: (Int) -> (Int) = incrementByThree
32+
public static var privateFunctionPointer: (Int) -> (Int) = { $0 }
33+
}
34+

test/SILOptimizer/default-cmo.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@
1111
import Module
1212
import ModuleTBD
1313

14+
// CHECK-LABEL: sil_global public_external [serialized] @$s6Module0A6StructV21publicFunctionPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int = {
15+
// CHECK: %0 = function_ref @$s6Module16incrementByThreeyS2iF
16+
17+
// CHECK-LABEL: sil_global public_external @$s6Module0A6StructV22privateFunctionPointeryS2icvpZ : $@callee_guaranteed (Int) -> Int{{$}}
18+
19+
public func callPublicFunctionPointer(_ x: Int) -> Int {
20+
return Module.ModuleStruct.publicFunctionPointer(x)
21+
}
22+
23+
public func callPrivateFunctionPointer(_ x: Int) -> Int {
24+
return Module.ModuleStruct.privateFunctionPointer(x)
25+
}
26+
1427
// CHECK-LABEL: sil @$s4Main11doIncrementyS2iF
1528
// CHECK-NOT: function_ref
1629
// CHECK-NOT: apply
@@ -73,3 +86,4 @@ public func getModuleKlassMember() -> Int {
7386
public func getModuleKlassMemberTBD() -> Int {
7487
return ModuleTBD.moduleKlassMember()
7588
}
89+

0 commit comments

Comments
 (0)