Skip to content

Commit e5cc525

Browse files
committed
IRGen: loosen linkage on vtable stubs for static linking
The linkage inferred by internal linking is overly restrictive. It uses the "internal linkage type" which is for translation unit local symbols, that is `static` storage. These symbols participate in linking and need to be given external storage but hidden visibility and no DLL storage in static linking. This permits them to participate in symbolic resolution during linking but are made module local, not LLVM module local.
1 parent 10f3828 commit e5cc525

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2025,7 +2025,9 @@ void IRGenModule::emitVTableStubs() {
20252025
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
20262026
else
20272027
ApplyIRLinkage(IRGen.Opts.InternalizeSymbols
2028-
? IRLinkage::Internal
2028+
? IRLinkage{llvm::GlobalValue::ExternalLinkage,
2029+
llvm::GlobalValue::HiddenVisibility,
2030+
llvm::GlobalValue::DefaultStorageClass}
20292031
: IRLinkage::ExternalExport).to(alias);
20302032
}
20312033
}

test/IRGen/static-vtable-stubs.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file --leading-lines %s %t
3+
// RUN: %swift-target-frontend -parse-as-library -static -O -module-name M -c -primary-file %t/A.swift %t/B.swift -S -emit-ir -o - | %FileCheck %t/A.swift -check-prefix CHECK
4+
// RUN: %swift-target-frontend -parse-as-library -static -O -module-name M -c %t/A.swift -primary-file %t/B.swift -S -emit-ir -o - | %FileCheck %t/B.swift -check-prefix CHECK
5+
6+
//--- A.swift
7+
open class C {
8+
private var i: [ObjectIdentifier:Any] = [:]
9+
}
10+
11+
// CHECK: @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvg" = hidden alias void (), void ()* @_swift_dead_method_stub
12+
// CHECK: @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvs" = hidden alias void (), void ()* @_swift_dead_method_stub
13+
// CHECK: @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvM" = hidden alias void (), void ()* @_swift_dead_method_stub
14+
15+
//--- B.swift
16+
final class D: C {
17+
}
18+
19+
// CHECK: declare swiftcc %swift.bridge* @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvg"(%T1M1CC* swiftself) #0
20+
// CHECK: declare swiftcc void @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvs"(%swift.bridge*, %T1M1CC* swiftself) #0
21+
// CHECK: declare swiftcc { i8*, %TSD* } @"$s1M1CC1i33_807E3D81CC6CDD898084F3279464DDF9LLSDySOypGvM"(i8* noalias dereferenceable(32), %T1M1CC* swiftself) #0

0 commit comments

Comments
 (0)