Skip to content

Commit 184ee71

Browse files
committed
IRGen: correctly cast C-function pointers in statically initialized globals.
This fixes a IRGen crash, introduced with swiftlang#35780 rdar://74358259
1 parent f45855d commit 184ee71

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/IRGen/GenConstant.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ llvm::Constant *irgen::emitConstantValue(IRGenModule &IGM, SILValue operand) {
249249
fnPtr = IGM.getConstantSignedPointer(fnPtr, authInfo.getKey(), nullptr,
250250
constantDiscriminator);
251251
}
252+
llvm::Type *ty = IGM.getTypeInfo(FRI->getType()).getStorageType();
253+
fnPtr = llvm::ConstantExpr::getBitCast(fnPtr, ty);
252254
return fnPtr;
253255
} else {
254256
llvm_unreachable("Unsupported SILInstruction in static initializer!");
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Testcase for an IRGen crash with function pointers in static globals and multi-threaded compilation.
2+
3+
// First test: check if the compilation succeeds and the code is correct.
4+
5+
// RUN: %empty-directory(%t)
6+
// RUN: %target-build-swift -O -module-name=Test %s -o %t/a.out
7+
// RUN: %target-codesign %t/a.out
8+
// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT
9+
10+
// Second test (bonus): check if the optimization is done: statically initialize a global with a C-function pointer
11+
12+
// RUN: %target-build-swift -O -module-name=Test %s -emit-sil | %FileCheck %s -check-prefix=CHECK-SIL
13+
14+
// REQUIRES: executable_test
15+
16+
17+
internal func cFn(_ i: Int) -> Int {
18+
return i + 1
19+
}
20+
21+
public struct S {
22+
// CHECK-SIL-LABEL: sil_global @$s4Test1SV6cFnPtryS2iXCvpZ : $@convention(c) (Int) -> Int = {
23+
// CHECK-SIL: %initval = function_ref @$s4Test3cFnyS2iFTo : $@convention(c) (Int) -> Int
24+
static public var cFnPtr: @convention(c) (Int) -> Int = cFn
25+
}
26+
27+
func testit() {
28+
// CHECK-OUTPUT: 28
29+
print(S.cFnPtr(27))
30+
}
31+
32+
testit()

0 commit comments

Comments
 (0)