Skip to content

Commit 18ab461

Browse files
authored
Merge pull request #78903 from tshortli/fix-weak-linking-for-potentially-unavailable-accessors
AST: Fix weak linking for potentially unavailable accessors in extensions
2 parents e2005fd + a6eb7e4 commit 18ab461

File tree

5 files changed

+216
-15
lines changed

5 files changed

+216
-15
lines changed

lib/AST/Availability.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -766,10 +766,12 @@ Decl::getAvailableAttrForPlatformIntroduction() const {
766766
// itself. This check relies on the fact that we cannot have nested
767767
// extensions.
768768

769-
DeclContext *DC = getDeclContext();
770-
if (auto *ED = dyn_cast<ExtensionDecl>(DC)) {
771-
if (auto attr = getDeclAvailableAttrForPlatformIntroduction(ED))
772-
return attr;
769+
if (auto parent =
770+
AvailabilityInference::parentDeclForInferredAvailability(this)) {
771+
if (auto *ED = dyn_cast<ExtensionDecl>(parent)) {
772+
if (auto attr = getDeclAvailableAttrForPlatformIntroduction(ED))
773+
return attr;
774+
}
773775
}
774776

775777
return std::nullopt;

test/IRGen/Inputs/weak_import_availability_helper.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ public func conditionallyAvailableFunction() {}
44
@available(macOS, unavailable)
55
public func unavailableFunction() {}
66

7+
@available(macOS 50, *)
8+
public func conditionallyAvailableOpaqueReturnFunction() -> some AlwaysAvailableProtocol {
9+
return AlwaysAvailableStruct()
10+
}
11+
712
@available(macOS 50, *)
813
public var conditionallyAvailableGlobal: Int {
914
get {return 0}
@@ -34,6 +39,53 @@ public protocol AlwaysAvailableProtocol {}
3439

3540
public struct AlwaysAvailableStruct {}
3641

42+
@available(macOS 50, *)
43+
extension AlwaysAvailableStruct {
44+
public func methodInConditionallyAvailableExtension() {}
45+
46+
public func opaqueReturnMethodInConditionallyAvailableExtension() -> some AlwaysAvailableProtocol {
47+
return AlwaysAvailableStruct()
48+
}
49+
50+
public var varInConditionallyAvailableExtension: Int {
51+
get {return 0}
52+
set {}
53+
}
54+
}
55+
56+
extension AlwaysAvailableStruct {
57+
@available(macOS 50, *)
58+
public func conditionallyAvailableMethodInExtension() {}
59+
60+
@available(macOS 50, *)
61+
public func conditionallyAvailableOpaqueReturnMethodInExtension() -> some AlwaysAvailableProtocol {
62+
return AlwaysAvailableStruct()
63+
}
64+
65+
@available(macOS 50, *)
66+
public var conditionallyAvailableVarInExtension: Int {
67+
get {return 0}
68+
set {}
69+
}
70+
}
71+
72+
@available(macOS 10.9, *)
73+
extension AlwaysAvailableStruct {
74+
@available(macOS 50, *)
75+
public func conditionallyAvailableMethodInExplicitlyAvailableExtension() {}
76+
77+
@available(macOS 50, *)
78+
public func conditionallyAvailableOpaqueReturnMethodInExplicitlyAvailableExtension() -> some AlwaysAvailableProtocol {
79+
return AlwaysAvailableStruct()
80+
}
81+
82+
@available(macOS 50, *)
83+
public var conditionallyAvailableVarInExplicitlyAvailablextension: Int {
84+
get {return 0}
85+
set {}
86+
}
87+
}
88+
3789
@available(macOS 50, *)
3890
extension AlwaysAvailableStruct : AlwaysAvailableProtocol {}
3991

test/IRGen/Inputs/weak_import_native_helper.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ public struct S {
3333
}
3434
}
3535

36+
extension S {
37+
@_weakLinked
38+
public func extensionFn() {}
39+
40+
@_weakLinked
41+
public var extensionProp: Int {
42+
get { return 1 }
43+
set {}
44+
}
45+
}
46+
3647
public enum E {
3748
case strong
3849

test/IRGen/weak_import_availability.swift

Lines changed: 137 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,56 @@
1212

1313
import weak_import_availability_helper
1414

15+
// AlwaysAvailableEnum.conditionallyAvailableCase enum case
16+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = extern_weak constant
17+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = external constant
18+
19+
20+
// Protocol witness table for AlwaysAvailableStruct: AlwaysAvailableProtocol
21+
// FIXME: We reference the witness table directly -- that's a bug since the
22+
// module is resilient. Should reference the conformance descriptor instead.
23+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = extern_weak global ptr
24+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = external global ptr
25+
26+
27+
// Protocol witness table for AlwaysAvailableStruct: UnavailableProtocol
28+
// CHECK-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA19UnavailableProtocolAAWP" = extern_weak global ptr
29+
30+
31+
// Opaque type descriptor for conditionallyAvailableOpaqueReturnFunction()
32+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper42conditionallyAvailableOpaqueReturnFunctionQryFQOMQ" = extern_weak global %swift.type_descriptor
33+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper42conditionallyAvailableOpaqueReturnFunctionQryFQOMQ" = external global %swift.type_descriptor
34+
35+
36+
// Opaque type descriptor for AlwaysAvailableStruct.opaqueReturnMethodInConditionallyAvailableExtension()
37+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV033opaqueReturnMethodInConditionallyF9ExtensionQryFQOMQ" = extern_weak global %swift.type_descriptor
38+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV033opaqueReturnMethodInConditionallyF9ExtensionQryFQOMQ" = external global %swift.type_descriptor
39+
40+
41+
// Opaque type descriptor for AlwaysAvailableStruct.conditionallyAvailableOpaqueReturnMethodInExtension()
42+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF29OpaqueReturnMethodInExtensionQryFQOMQ" = extern_weak global %swift.type_descriptor
43+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF29OpaqueReturnMethodInExtensionQryFQOMQ" = external global %swift.type_descriptor
44+
45+
46+
// Opaque type descriptor for AlwaysAvailableStruct.conditionallyAvailableOpaqueReturnMethodInExplicitlyAvailableExtension()
47+
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf30OpaqueReturnMethodInExplicitlyF9ExtensionQryFQOMQ" = extern_weak global %swift.type_descriptor
48+
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf30OpaqueReturnMethodInExplicitlyF9ExtensionQryFQOMQ" = external global %swift.type_descriptor
49+
50+
1551
public func useConditionallyAvailableCase(e: AlwaysAvailableEnum) {
1652
switch e {
1753
case .alwaysAvailableCase: break
1854
case .conditionallyAvailableCase: break
1955
}
2056
}
2157

22-
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = extern_weak constant i32
23-
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper19AlwaysAvailableEnumO013conditionallyF4CaseyA2CmFWC" = external constant i32
24-
2558
func useConformance<T : AlwaysAvailableProtocol>(_: T.Type) {}
2659

2760
@available(macOS 50, *)
2861
public func useConditionallyAvailableConformance() {
2962
useConformance(AlwaysAvailableStruct.self)
3063
}
3164

32-
// FIXME: We reference the witness table directly -- that's a bug since the module is resilient. Should reference the
33-
// conformance descriptor instead.
34-
35-
// CHECK-OLD-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = extern_weak global ptr
36-
// CHECK-NEW-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA0eF8ProtocolAAWP" = external global ptr
37-
3865
@available(macOS, unavailable)
3966
func useUnavailableConformance<T : UnavailableProtocol>(_: T.Type) {}
4067

@@ -43,8 +70,6 @@ public func useUnavailableConformance() {
4370
useUnavailableConformance(AlwaysAvailableStruct.self)
4471
}
4572

46-
// CHECK-LABEL: @"$s31weak_import_availability_helper21AlwaysAvailableStructVAA19UnavailableProtocolAAWP" = extern_weak global ptr, align 8
47-
4873
@available(macOS 50, *)
4974
public func callConditionallyAvailableFunction() {
5075
conditionallyAvailableFunction()
@@ -60,6 +85,14 @@ public func callUnavailableFunction() {
6085

6186
// CHECK-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper19unavailableFunctionyyF"()
6287

88+
@available(macOS 50, *)
89+
public func callConditionallyAvailableOpaqueReturnFunction() {
90+
blackHole(conditionallyAvailableOpaqueReturnFunction())
91+
}
92+
93+
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper42conditionallyAvailableOpaqueReturnFunctionQryF"
94+
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper42conditionallyAvailableOpaqueReturnFunctionQryF"
95+
6396
@available(macOS 50, *)
6497
public func useConditionallyAvailableGlobal() {
6598
_ = conditionallyAvailableGlobal
@@ -113,6 +146,99 @@ public func useConditionallyAvailableMethod(s: ConditionallyAvailableStruct) {
113146
// CHECK-OLD-LABEL: declare extern_weak swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(ptr noalias swiftself)
114147
// CHECK-NEW-LABEL: declare swiftcc void @"$s31weak_import_availability_helper28ConditionallyAvailableStructV013conditionallyF6MethodyyF"(ptr noalias swiftself)
115148

149+
@available(macOS 50, *)
150+
public func useMethodInConditionallyAvailableExtension(s: AlwaysAvailableStruct) {
151+
s.methodInConditionallyAvailableExtension()
152+
}
153+
154+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV021methodInConditionallyF9ExtensionyyF"
155+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV021methodInConditionallyF9ExtensionyyF"
156+
157+
@available(macOS 50, *)
158+
public func useOpaqueReturnMethodInConditionallyAvailableExtension(s: AlwaysAvailableStruct) {
159+
blackHole(s.opaqueReturnMethodInConditionallyAvailableExtension())
160+
}
161+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV033opaqueReturnMethodInConditionallyF9ExtensionQryF"
162+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV033opaqueReturnMethodInConditionallyF9ExtensionQryF"
163+
164+
@available(macOS 50, *)
165+
public func useVarInConditionallyAvailableExtension(s: inout AlwaysAvailableStruct) {
166+
_ = s.varInConditionallyAvailableExtension
167+
s.varInConditionallyAvailableExtension = 0
168+
s.varInConditionallyAvailableExtension += 0
169+
}
170+
171+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivg"
172+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivs"
173+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivM"
174+
175+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivg"
176+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivs"
177+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV018varInConditionallyF9ExtensionSivM"
178+
179+
@available(macOS 50, *)
180+
public func useConditionallyAvailableMethodInExtension(s: AlwaysAvailableStruct) {
181+
s.conditionallyAvailableMethodInExtension()
182+
}
183+
184+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF17MethodInExtensionyyF"
185+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF17MethodInExtensionyyF"
186+
187+
@available(macOS 50, *)
188+
public func useConditionallyAvailableOpaqueReturnMethodInExtension(s: AlwaysAvailableStruct) {
189+
blackHole(s.conditionallyAvailableOpaqueReturnMethodInExtension())
190+
}
191+
192+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF29OpaqueReturnMethodInExtensionQryF"
193+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF29OpaqueReturnMethodInExtensionQryF"
194+
195+
@available(macOS 50, *)
196+
public func useConditionallyAvailableVarInExtension(s: inout AlwaysAvailableStruct) {
197+
_ = s.conditionallyAvailableVarInExtension
198+
s.conditionallyAvailableVarInExtension = 0
199+
s.conditionallyAvailableVarInExtension += 0
200+
}
201+
202+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivg"
203+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivs"
204+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivM"
205+
206+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivg"
207+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivs"
208+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF14VarInExtensionSivM"
209+
210+
@available(macOS 50, *)
211+
public func useConditionallyAvailableMethodInExplicitlyAvailableExtension(s: AlwaysAvailableStruct) {
212+
s.conditionallyAvailableMethodInExplicitlyAvailableExtension()
213+
}
214+
215+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf18MethodInExplicitlyF9ExtensionyyF"
216+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf18MethodInExplicitlyF9ExtensionyyF"
217+
218+
@available(macOS 50, *)
219+
public func useConditionallyAvailableOpaqueReturnMethodInExplicitlyAvailableExtension(s: AlwaysAvailableStruct) {
220+
blackHole(s.conditionallyAvailableOpaqueReturnMethodInExplicitlyAvailableExtension())
221+
}
222+
223+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf30OpaqueReturnMethodInExplicitlyF9ExtensionQryF"
224+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyf30OpaqueReturnMethodInExplicitlyF9ExtensionQryF"
225+
226+
227+
@available(macOS 50, *)
228+
public func useConditionallyAvailableVarInExplicitlyAvailableExtension(s: inout AlwaysAvailableStruct) {
229+
_ = s.conditionallyAvailableVarInExplicitlyAvailablextension
230+
s.conditionallyAvailableVarInExplicitlyAvailablextension = 0
231+
s.conditionallyAvailableVarInExplicitlyAvailablextension += 0
232+
}
233+
234+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivg"
235+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivs"
236+
// CHECK-OLD-LABEL: declare extern_weak swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivM"
237+
238+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivg"
239+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivs"
240+
// CHECK-NEW-LABEL: declare swiftcc {{.+}} @"$s31weak_import_availability_helper21AlwaysAvailableStructV013conditionallyF32VarInExplicitlyAvailablextensionSivM"
241+
116242
@available(macOS, unavailable)
117243
public func useUnavailableStruct() {
118244
blackHole(UnavailableStruct.self)

test/IRGen/weak_import_native.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ func testStruct() {
5858
s[0] = z
5959
s[0] += 1
6060

61+
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1SV11extensionFnyyF"
62+
s.extensionFn()
63+
64+
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1SV13extensionPropSivg"
65+
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1SV13extensionPropSivs"
66+
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper1SV13extensionPropSivM"
67+
let yy = s.extensionProp
68+
s.extensionProp = yy
69+
s.extensionProp += 1
70+
6171
// CHECK-DAG: declare extern_weak {{.+}} @"$s25weak_import_native_helper5WeakSV0A6MemberyyF"
6272
let w = WeakS()
6373
w.weakMember()

0 commit comments

Comments
 (0)