@@ -17,25 +17,73 @@ import SwiftShims
1717///
1818/// This is a magic entry point known to the compiler. It is called in
1919/// 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
2051@_semantics ( " availability.osversion " )
2152@_effects ( readnone)
2253@_unavailableInEmbedded
2354public func _stdlib_isOSVersionAtLeast(
2455 _ major: Builtin . Word ,
2556 _ minor: Builtin . Word ,
2657 _ 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
2770) -> Builtin . Int1 {
2871#if (os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(visionOS)) && SWIFT_RUNTIME_OS_VERSIONING
2972 if Int ( major) == 9999 {
3073 return true . _value
3174 }
32- let runningVersion = _swift_stdlib_operatingSystemVersion ( )
33-
34- let result =
35- ( runningVersion. majorVersion, runningVersion. minorVersion, runningVersion. patchVersion)
36- >= ( Int ( major) , Int ( minor) , Int ( patch) )
3775
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
3987#else
4088 // FIXME: As yet, there is no obvious versioning standard for platforms other
4189 // than Darwin-based OSes, so we just assume false for now.
0 commit comments