@@ -17,25 +17,73 @@ import SwiftShims
17
17
///
18
18
/// This is a magic entry point known to the compiler. It is called in
19
19
/// generated code for API availability checking.
20
+ ///
21
+ /// This is marked @_transparent on iOS to work around broken availability
22
+ /// checking for iOS apps running on macOS (rdar://83378814). libswiftCore uses
23
+ /// the macOS platform identifier for its version check in that scenario,
24
+ /// causing all queries to return true. When this function is inlined into the
25
+ /// caller, the compiler embeds the correct platform identifier in the client
26
+ /// code, and we get the right answer.
27
+ ///
28
+ /// @_transparent breaks the optimizer's ability to remove availability checks
29
+ /// that are unnecessary due to the current deployment target. We call through
30
+ /// to the _stdlib_isOSVersionAtLeast_AEIC function below to work around this,
31
+ /// as the optimizer is able to perform this optimization for a
32
+ /// @_alwaysEmitIntoClient function. We can't use @_alwaysEmitIntoClient
33
+ /// directly on this call because it would break ABI for existing apps.
34
+ ///
35
+ /// `@_transparent` breaks the interpreter mode on macOS, as it creates a direct
36
+ /// reference to ___isPlatformVersionAtLeast from compiler-rt, and the
37
+ /// interpreter doesn't currently know how to load symbols from compiler-rt.
38
+ /// Since `@_transparent` is only necessary for iOS apps, we only apply it on
39
+ /// iOS, not any other which would inherit/remap iOS availability.
40
+ #if os(iOS) && !os(xrOS)
41
+ @_effects ( readnone)
42
+ @_transparent
43
+ public func _stdlib_isOSVersionAtLeast(
44
+ _ major: Builtin . Word ,
45
+ _ minor: Builtin . Word ,
46
+ _ patch: Builtin . Word
47
+ ) -> Builtin . Int1 {
48
+ return _stdlib_isOSVersionAtLeast_AEIC ( major, minor, patch)
49
+ }
50
+ #else
20
51
@_semantics ( " availability.osversion " )
21
52
@_effects ( readnone)
22
53
@_unavailableInEmbedded
23
54
public func _stdlib_isOSVersionAtLeast(
24
55
_ major: Builtin . Word ,
25
56
_ minor: Builtin . Word ,
26
57
_ patch: Builtin . Word
58
+ ) -> Builtin . Int1 {
59
+ return _stdlib_isOSVersionAtLeast_AEIC ( major, minor, patch)
60
+ }
61
+ #endif
62
+
63
+ @_semantics ( " availability.osversion " )
64
+ @_effects ( readnone)
65
+ @_alwaysEmitIntoClient
66
+ public func _stdlib_isOSVersionAtLeast_AEIC(
67
+ _ major: Builtin . Word ,
68
+ _ minor: Builtin . Word ,
69
+ _ patch: Builtin . Word
27
70
) -> Builtin . Int1 {
28
71
#if (os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)) && SWIFT_RUNTIME_OS_VERSIONING
29
72
if Int ( major) == 9999 {
30
73
return true . _value
31
74
}
32
- let runningVersion = _swift_stdlib_operatingSystemVersion ( )
33
-
34
- let result =
35
- ( runningVersion. majorVersion, runningVersion. minorVersion, runningVersion. patchVersion)
36
- >= ( Int ( major) , Int ( minor) , Int ( patch) )
37
75
38
- return result. _value
76
+ let queryVersion = ( Int ( major) , Int ( minor) , Int ( patch) )
77
+ let major32 = Int32 ( truncatingIfNeeded: Int ( queryVersion. 0 ) )
78
+ let minor32 = Int32 ( truncatingIfNeeded: Int ( queryVersion. 1 ) )
79
+ let patch32 = Int32 ( truncatingIfNeeded: Int ( queryVersion. 2 ) )
80
+
81
+ // Defer to a builtin that calls clang's version checking builtin from
82
+ // compiler-rt.
83
+ let result32 = Int32 ( Builtin . targetOSVersionAtLeast ( major32. _value,
84
+ minor32. _value,
85
+ patch32. _value) )
86
+ return ( result32 != ( 0 as Int32 ) ) . _value
39
87
#else
40
88
// FIXME: As yet, there is no obvious versioning standard for platforms other
41
89
// than Darwin-based OSes, so we just assume false for now.
0 commit comments