Skip to content

Commit b563dc0

Browse files
committed
Frontend: Replace the abi magic value accepted by -target-min-inlining-version with a min magic value instead. The new value corresponds to the OS versions in which Swift was introduced. The introduction OS is a better floor for availability checking than the OS in which Swift became ABI stable because inlinable functions may reference clang declarations which have availability between Swift's introduction and ABI stability and framework developers ought to get diagnostics for unguarded use of those APIs in inlinable code.
1 parent f807ef9 commit b563dc0

File tree

4 files changed

+64
-27
lines changed

4 files changed

+64
-27
lines changed

include/swift/Basic/Platform.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ namespace swift {
5555
bool triplesAreValidForZippering(const llvm::Triple &target,
5656
const llvm::Triple &targetVariant);
5757

58+
/// Returns the VersionTuple at which Swift first became available for the OS
59+
/// represented by `triple`.
5860
const Optional<llvm::VersionTuple>
59-
minimumABIStableOSVersionForTriple(const llvm::Triple &triple);
61+
minimumAvailableOSVersionForTriple(const llvm::Triple &triple);
6062

6163
/// Returns true if the given triple represents an OS that has all the
6264
/// "built-in" ABI-stable libraries (stdlib and _Concurrency)

lib/Basic/Platform.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,20 @@ bool swift::triplesAreValidForZippering(const llvm::Triple &target,
8080
}
8181

8282
const Optional<llvm::VersionTuple>
83-
swift::minimumABIStableOSVersionForTriple(const llvm::Triple &triple) {
83+
swift::minimumAvailableOSVersionForTriple(const llvm::Triple &triple) {
8484
if (triple.isMacOSX())
85-
return llvm::VersionTuple(10, 14, 4);
85+
return llvm::VersionTuple(10, 10, 0);
8686

87-
if (triple.isiOS() /* including tvOS */)
88-
return llvm::VersionTuple(12, 2);
87+
// Note: this must come before checking iOS since that returns true for
88+
// both iOS and tvOS.
89+
if (triple.isTvOS())
90+
return llvm::VersionTuple(9, 0);
91+
92+
if (triple.isiOS())
93+
return llvm::VersionTuple(8, 0);
8994

9095
if (triple.isWatchOS())
91-
return llvm::VersionTuple(5, 2);
96+
return llvm::VersionTuple(2, 0);
9297

9398
return None;
9499
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -803,15 +803,12 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
803803
// First, set up default minimum inlining target versions.
804804
auto getDefaultMinimumInliningTargetVersion =
805805
[&](const llvm::Triple &triple) -> llvm::VersionTuple {
806-
#if SWIFT_DEFAULT_TARGET_MIN_INLINING_VERSION_TO_ABI
807-
// In ABI-stable modules, default to the version where the target's ABI
808-
// was first frozen; older versions will use that one's backwards
809-
// compatibility libraries.
806+
#if SWIFT_DEFAULT_TARGET_MIN_INLINING_VERSION_TO_MIN
807+
// In ABI-stable modules, default to the version when Swift first became
808+
// available.
810809
if (FrontendOpts.EnableLibraryEvolution)
811-
if (auto abiStability = minimumABIStableOSVersionForTriple(triple))
812-
// FIXME: Should we raise it to the minimum supported OS version for
813-
// architectures which were born ABI-stable?
814-
return *abiStability;
810+
if (auto minTriple = minimumAvailableOSVersionForTriple(triple))
811+
return minTriple;
815812
#endif
816813

817814
// In ABI-unstable modules, we will never have to interoperate with
@@ -834,10 +831,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
834831
if (!A)
835832
return None;
836833

834+
if (StringRef(A->getValue()) == "min")
835+
return minimumAvailableOSVersionForTriple(Opts.Target);
837836
if (StringRef(A->getValue()) == "target")
838837
return Opts.getMinPlatformVersion();
839-
if (StringRef(A->getValue()) == "abi")
840-
return minimumABIStableOSVersionForTriple(Opts.Target);
841838

842839
if (auto vers = version::Version::parseVersionString(A->getValue(),
843840
SourceLoc(), &Diags))

test/attr/attr_inlinable_available.swift

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111

1212
// REQUIRES: swift_stable_abi
1313

14-
1514
// Primary execution of this test. Uses the default minimum inlining version,
16-
// which is the version when the ABI became stable.
17-
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution -target %target-next-stable-abi-triple -target-min-inlining-version abi
15+
// which is the version when Swift was introduced.
16+
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution -target %target-next-stable-abi-triple -target-min-inlining-version min
1817

1918

2019
// Check that these rules are only applied when requested and that at least some
@@ -34,12 +33,12 @@ public struct NoAvailable {
3433
@usableFromInline internal init() {}
3534
}
3635

37-
@available(macOS 10.14.3, iOS 12.1, tvOS 12.1, watchOS 5.1, *)
36+
@available(macOS 10.9, iOS 7.0, tvOS 8.0, watchOS 1.0, *)
3837
public struct BeforeInliningTarget {
3938
@usableFromInline internal init() {}
4039
}
4140

42-
@available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *)
41+
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
4342
public struct AtInliningTarget {
4443
@usableFromInline internal init() {}
4544
}
@@ -90,7 +89,7 @@ public func deployedUseNoAvailable( // expected-note 5 {{add @available attribut
9089
}
9190
}
9291

93-
@available(macOS 10.14.3, iOS 12.1, tvOS 12.1, watchOS 5.1, *)
92+
@available(macOS 10.9, iOS 7.0, tvOS 8.0, watchOS 1.0, *)
9493
public func deployedUseBeforeInliningTarget(
9594
_: NoAvailable,
9695
_: BeforeInliningTarget,
@@ -115,7 +114,7 @@ public func deployedUseBeforeInliningTarget(
115114
}
116115
}
117116

118-
@available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *)
117+
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
119118
public func deployedUseAtInliningTarget(
120119
_: NoAvailable,
121120
_: BeforeInliningTarget,
@@ -248,7 +247,7 @@ public func deployedUseAfterDeploymentTarget(
248247
}
249248
}
250249

251-
@available(macOS 10.14.3, iOS 12.1, tvOS 12.1, watchOS 5.1, *)
250+
@available(macOS 10.9, iOS 7.0, tvOS 8.0, watchOS 1.0, *)
252251
@inlinable public func inlinedUseBeforeInliningTarget(
253252
_: NoAvailable,
254253
_: BeforeInliningTarget,
@@ -264,7 +263,7 @@ public func deployedUseAfterDeploymentTarget(
264263
_ = NoAvailable()
265264
_ = BeforeInliningTarget()
266265
_ = AtInliningTarget()
267-
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} {{18-25=10.14.5}} || {{31-35=12.3}} || {{42-46=12.3}} || {{56-59=5.3}}
266+
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}}
268267
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
269268
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
270269

@@ -279,7 +278,7 @@ public func deployedUseAfterDeploymentTarget(
279278
}
280279
}
281280

282-
@available(macOS 10.14.4, iOS 12.2, tvOS 12.2, watchOS 5.2, *)
281+
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
283282
@inlinable public func inlinedUseAtInliningTarget(
284283
_: NoAvailable,
285284
_: BeforeInliningTarget,
@@ -295,7 +294,7 @@ public func deployedUseAfterDeploymentTarget(
295294
_ = NoAvailable()
296295
_ = BeforeInliningTarget()
297296
_ = AtInliningTarget()
298-
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} {{18-25=10.14.5}} || {{31-35=12.3}} || {{42-46=12.3}} || {{56-59=5.3}}
297+
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}}
299298
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
300299
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
301300

@@ -426,6 +425,40 @@ internal func fn() {
426425
}
427426
}
428427

428+
// @_backDeploy acts like @inlinable.
429+
430+
@available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *)
431+
@_backDeploy(macOS 999.0, iOS 999.0, tvOS 999.0, watchOS 999.0)
432+
public func backDeployedToInliningTarget(
433+
_: NoAvailable,
434+
_: BeforeInliningTarget,
435+
_: AtInliningTarget,
436+
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}}
437+
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}}
438+
_: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}}
439+
) {
440+
defer {
441+
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
442+
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
443+
}
444+
_ = NoAvailable()
445+
_ = BeforeInliningTarget()
446+
_ = AtInliningTarget()
447+
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}}
448+
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
449+
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}}
450+
451+
if #available(macOS 10.14.5, iOS 12.3, tvOS 12.3, watchOS 5.3, *) {
452+
_ = BetweenTargets()
453+
}
454+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
455+
_ = AtDeploymentTarget()
456+
}
457+
if #available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) {
458+
_ = AfterDeploymentTarget()
459+
}
460+
}
461+
429462
// Default arguments act like @inlinable.
430463

431464
public func defaultArgsUseNoAvailable( // expected-note 3 {{add @available attribute}}

0 commit comments

Comments
 (0)