Skip to content

Commit 9677ff6

Browse files
authored
Merge pull request #64595 from tshortli/weak-link-unavailable-symbols-redux-5.9
[5.9] IRGen: Weakly link symbols for unavailable declarations
2 parents badf58d + dabf0ce commit 9677ff6

File tree

6 files changed

+128
-12
lines changed

6 files changed

+128
-12
lines changed

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,12 @@ bool Decl::isAlwaysWeakImported() const {
11261126
if (getAttrs().hasAttribute<WeakLinkedAttr>())
11271127
return true;
11281128

1129+
// FIXME: Weak linking on Windows is not yet supported
1130+
// https://github.com/apple/swift/issues/53303
1131+
if (getSemanticUnavailableAttr() &&
1132+
!getASTContext().LangOpts.Target.isOSWindows())
1133+
return true;
1134+
11291135
if (auto *accessor = dyn_cast<AccessorDecl>(this))
11301136
return accessor->getStorage()->isAlwaysWeakImported();
11311137

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,51 @@
11
@available(macOS 10.50, *)
22
public func conditionallyAvailableFunction() {}
33

4+
@available(macOS, unavailable)
5+
public func unavailableFunction() {}
6+
47
@available(macOS 10.50, *)
58
public var conditionallyAvailableGlobal: Int {
69
get {return 0}
710
set {}
811
}
912

13+
@available(macOS, unavailable)
14+
public var unavailableGlobal: Int {
15+
get {return 0}
16+
set {}
17+
}
18+
1019
@available(macOS 10.50, *)
1120
public struct ConditionallyAvailableStruct {
1221
public func conditionallyAvailableMethod() {}
1322
}
1423

24+
extension ConditionallyAvailableStruct {
25+
public struct NestedStruct {}
26+
}
27+
28+
@available(macOS, unavailable)
29+
public struct UnvailableStruct {
30+
public func unavailableMethod() {}
31+
}
32+
1533
public protocol AlwaysAvailableProtocol {}
1634

1735
public struct AlwaysAvailableStruct {}
1836

1937
@available(macOS 10.50, *)
2038
extension AlwaysAvailableStruct : AlwaysAvailableProtocol {}
2139

40+
@available(macOS, unavailable)
41+
public protocol UnavailableProtocol {}
42+
43+
@available(macOS, unavailable)
44+
extension AlwaysAvailableStruct : UnavailableProtocol {}
45+
2246
public enum AlwaysAvailableEnum {
2347
case alwaysAvailableCase
2448

2549
@available(macOS 10.50, *)
2650
case conditionallyAvailableCase
27-
}
51+
}

test/IRGen/float16_macos.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-frontend -emit-ir %s -target x86_64-apple-macos10.15 | %FileCheck %s --check-prefix=CHECK10
2-
// RUN: %target-swift-frontend -emit-ir %s -target x86_64-apple-macos11 | %FileCheck %s --check-prefix=CHECK11
1+
// RUN: %target-swift-frontend -emit-ir %s -target x86_64-apple-macos10.15 | %FileCheck %s
2+
// RUN: %target-swift-frontend -emit-ir %s -target x86_64-apple-macos11 | %FileCheck %s
33

44
// REQUIRES: OS=macosx
55
// REQUIRES: CPU=x86_64
@@ -11,5 +11,4 @@ public struct Float16Wrapper {
1111
var x: Float16
1212
}
1313

14-
// CHECK10-LABEL: @"$ss7Float16VMn" = extern_weak global %swift.type_descriptor
15-
// CHECK11-LABEL: @"$ss7Float16VMn" = external global %swift.type_descriptor
14+
// CHECK-LABEL: @"$ss7Float16VMn" = extern_weak global %swift.type_descriptor

test/IRGen/weak_import_availability.swift

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/weak_import_availability_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_availability_helper.swift -enable-library-evolution
2+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx10.50 -emit-module -emit-module-path %t/weak_import_availability_helper.swiftmodule -parse-as-library %S/Inputs/weak_import_availability_helper.swift -enable-library-evolution
33
//
4-
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir | %FileCheck %s --check-prefix=CHECK-OLD
5-
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 | %FileCheck %s --check-prefix=CHECK-NEW
6-
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 | %FileCheck %s --check-prefix=CHECK-NEW
4+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir | %FileCheck %s --check-prefixes=CHECK,CHECK-OLD
5+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 | %FileCheck %s --check-prefixes=CHECK,CHECK-NEW
6+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 | %FileCheck %s --check-prefixes=CHECK,CHECK-NEW
77

8-
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 -weak-link-at-target | %FileCheck %s --check-prefix=CHECK-OLD
9-
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 -weak-link-at-target | %FileCheck %s --check-prefix=CHECK-NEW
8+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.50 -weak-link-at-target | %FileCheck %s --check-prefixes=CHECK,CHECK-OLD
9+
// RUN: %target-swift-frontend -primary-file %s -I %t -emit-ir -target %target-cpu-apple-macosx10.60 -weak-link-at-target | %FileCheck %s --check-prefixes=CHECK,CHECK-NEW
1010

1111
// REQUIRES: OS=macosx
1212

@@ -35,6 +35,16 @@ public func useConditionallyAvailableConformance() {
3535
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = extern_weak global i8*
3636
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = external global i8*
3737

38+
@available(macOS, unavailable)
39+
func useUnavailableConformance<T : UnavailableProtocol>(_: T.Type) {}
40+
41+
@available(macOS, unavailable)
42+
public func useUnavailableConformance() {
43+
useUnavailableConformance(AlwaysAvailableStruct.self)
44+
}
45+
46+
// CHECK-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA19UnavailableProtocolAAWP" = extern_weak global i8*, align 8
47+
3848
@available(macOS 10.50, *)
3949
public func callConditionallyAvailableFunction() {
4050
conditionallyAvailableFunction()
@@ -43,6 +53,13 @@ public func callConditionallyAvailableFunction() {
4353
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper30conditionallyAvailableFunctionyyF"()
4454
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper30conditionallyAvailableFunctionyyF"()
4555

56+
@available(macOS, unavailable)
57+
public func callUnavailableFunction() {
58+
unavailableFunction()
59+
}
60+
61+
// CHECK-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper19unavailableFunctionyyF"()
62+
4663
@available(macOS 10.50, *)
4764
public func useConditionallyAvailableGlobal() {
4865
_ = conditionallyAvailableGlobal
@@ -56,17 +73,56 @@ public func useConditionallyAvailableGlobal() {
5673
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivs"(i64)
5774
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivs"(i64)
5875

76+
// CHECK-OLD-LABEL: declare extern_weak swiftcc { i8*, %TSi* } @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivM"(i8* noalias dereferenceable(32))
77+
// CHECK-NEW-LABEL: declare swiftcc { i8*, %TSi* } @"$s31weak_import_availability_helper28conditionallyAvailableGlobalSivM"(i8* noalias dereferenceable(32))
78+
79+
@available(macOS, unavailable)
80+
public func useUnavailableGlobal() {
81+
_ = unavailableGlobal
82+
unavailableGlobal = 0
83+
unavailableGlobal += 1
84+
}
85+
86+
// CHECK-LABEL: declare extern_weak swiftcc i64 @"$s31weak_import_availability_helper17unavailableGlobalSivg"()
87+
// CHECK-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper17unavailableGlobalSivs"(i64)
88+
// CHECK-LABEL: declare extern_weak swiftcc { i8*, %TSi* } @"$s31weak_import_availability_helper17unavailableGlobalSivM"(i8* noalias dereferenceable(32))
89+
5990
func blackHole<T>(_: T) {}
6091

6192
@available(macOS 10.50, *)
6293
public func useConditionallyAvailableStruct() {
6394
blackHole(ConditionallyAvailableStruct.self)
6495
}
6596

97+
// CHECK-OLD-LABEL: declare extern_weak swiftcc %swift.metadata_response @"$s31weak_import_availability_helper28ConditionallyAvailableStructVMa"(i64)
98+
// CHECK-NEW-LABEL: declare swiftcc %swift.metadata_response @"$s31weak_import_availability_helper28ConditionallyAvailableStructVMa"(i64)
99+
100+
@available(macOS 10.50, *)
101+
public func useNestedConditionallyAvailableStruct() {
102+
blackHole(ConditionallyAvailableStruct.NestedStruct.self)
103+
}
104+
105+
// CHECK-OLD-LABEL: declare extern_weak swiftcc %swift.metadata_response @"$s31weak_import_availability_helper28ConditionallyAvailableStructV06NestedG0VMa"(i64)
106+
// CHECK-NEW-LABEL: declare swiftcc %swift.metadata_response @"$s31weak_import_availability_helper28ConditionallyAvailableStructV06NestedG0VMa"(i64)
107+
66108
@available(macOS 10.50, *)
67109
public func useConditionallyAvailableMethod(s: ConditionallyAvailableStruct) {
68110
s.conditionallyAvailableMethod()
69111
}
70112

71113
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(%swift.opaque* noalias nocapture swiftself)
72114
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(%swift.opaque* noalias nocapture swiftself)
115+
116+
@available(macOS, unavailable)
117+
public func useUnavailableStruct() {
118+
blackHole(UnvailableStruct.self)
119+
}
120+
121+
// CHECK-LABEL: declare extern_weak swiftcc %swift.metadata_response @"$s31weak_import_availability_helper16UnvailableStructVMa"(i64)
122+
123+
@available(macOS, unavailable)
124+
public func useUnavailableMethod(s: UnvailableStruct) {
125+
s.unavailableMethod()
126+
}
127+
128+
// CHECK-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper16UnvailableStructV17unavailableMethodyyF"(%swift.opaque* noalias nocapture swiftself)

test/SILGen/objc_init_unavailable.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk) -enable-objc-interop -import-objc-header %S/Inputs/objc_init_unavailable.h %s | %FileCheck %s
22
// REQUIRES: objc_interop
3+
// REQUIRES: OS=macosx
34

45
@available(macOS, unavailable)
56
public func callUnavailableInit(name: String) -> ClassWithUnavailableInit {
67
return ClassWithUnavailableInit(bundleID: name)
78
}
89

9-
// CHECK-LABEL: sil [ossa] @$s21objc_init_unavailable19callUnavailableInit4nameSo09ClassWitheF0CSS_tF : $@convention(thin) (@guaranteed String) -> @owned ClassWithUnavailableInit {
10+
// CHECK-LABEL: sil [weak_imported] [ossa] @$s21objc_init_unavailable19callUnavailableInit4nameSo09ClassWitheF0CSS_tF : $@convention(thin) (@guaranteed String) -> @owned ClassWithUnavailableInit {
1011
// CHECK: function_ref @$sSo24ClassWithUnavailableInitC8bundleIDABSgSSSg_tcfC : $@convention(method) (@owned Optional<String>, @thick ClassWithUnavailableInit.Type) -> @owned Optional<ClassWithUnavailableInit>
1112
// CHECK: return
1213

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: %target-build-swift-dylib(%t/%target-library-name(Library)) -emit-module -emit-module-path %t/Library.swiftmodule -module-name Library -parse-as-library %t/Library.swift -swift-version 5 -enable-library-evolution
4+
// RUN: %target-build-swift-dylib(%t/%target-library-name(ClientLibrary)) %t/ClientA.swift %t/ClientB.swift -I%t -L%t -swift-version 5 -lLibrary
5+
6+
//--- Library.swift
7+
8+
@available(*, unavailable)
9+
public struct UnavailableStruct {}
10+
11+
//--- ClientA.swift
12+
13+
import Library
14+
15+
@inline(never)
16+
func blackHole<T>(_ t: T) {}
17+
18+
@available(*, unavailable)
19+
public func foo() {
20+
blackHole(UnavailableStruct.self)
21+
}
22+
23+
//--- ClientB.swift
24+
25+
import Library
26+
27+
@available(*, unavailable)
28+
public func bar() {
29+
blackHole(UnavailableStruct.self)
30+
}

0 commit comments

Comments
 (0)