Skip to content

Commit cc16ffe

Browse files
committed
AST: Fix AvailabilityContext platform range for certain targets.
#79807 caused a regression in which `AvailabilityContext` stopped tracking the available version range for the active platform domain for certain platforms. Fix this by reverting to checking `AvailabilityDomain::isActive()` to determine when a given platform `AvailabilityDomain` represents the target platform. The compiler's existing mapping from target triple to platform domain is incomplete and it's not clear to me whether fixing that could cause other regressions. Resolves rdar://147413616.
1 parent 6ca8e0d commit cc16ffe

File tree

7 files changed

+33
-82
lines changed

7 files changed

+33
-82
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -152,16 +152,6 @@ class AvailabilityDomain final {
152152
return AvailabilityDomain(domain);
153153
}
154154

155-
/// Returns the most specific platform domain for the target of the
156-
/// compilation context.
157-
static std::optional<AvailabilityDomain>
158-
forTargetPlatform(const ASTContext &ctx);
159-
160-
/// Returns the most specific platform domain for the target variant of the
161-
/// compilation context.
162-
static std::optional<AvailabilityDomain>
163-
forTargetVariantPlatform(const ASTContext &ctx);
164-
165155
/// Returns the built-in availability domain identified by the given string.
166156
static std::optional<AvailabilityDomain>
167157
builtinDomainForString(StringRef string, const DeclContext *declContext);
@@ -227,10 +217,6 @@ class AvailabilityDomain final {
227217
/// compilation context.
228218
bool isActive(const ASTContext &ctx) const;
229219

230-
/// Returns true if this domain is a platform domain that is contained by the
231-
/// set of active platform-specific domains.
232-
bool isActiveForTargetPlatform(const ASTContext &ctx) const;
233-
234220
/// Returns the domain's minimum available range for type checking. For
235221
/// example, for the domain of the platform that compilation is targeting,
236222
/// this version is specified with the `-target` option. For the Swift

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7097,8 +7097,9 @@ ValueOwnership swift::asValueOwnership(ParameterOwnership o) {
70977097
}
70987098

70997099
AvailabilityDomain ASTContext::getTargetAvailabilityDomain() const {
7100-
if (auto domain = AvailabilityDomain::forTargetPlatform(*this))
7101-
return *domain;
7100+
auto platform = swift::targetPlatform(LangOpts);
7101+
if (platform != PlatformKind::none)
7102+
return AvailabilityDomain::forPlatform(platform);
71027103

71037104
// Fall back to the universal domain for triples without a platform.
71047105
return AvailabilityDomain::forUniversal();

lib/AST/Availability.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,11 +552,15 @@ getRootTargetDomains(const ASTContext &ctx) {
552552
if (ctx.LangOpts.hasFeature(Feature::Embedded))
553553
return domains;
554554

555-
if (auto targetDomain = AvailabilityDomain::forTargetPlatform(ctx))
556-
domains.insert(targetDomain->getRootDomain());
557-
558-
if (auto variantDomain = AvailabilityDomain::forTargetVariantPlatform(ctx))
559-
domains.insert(variantDomain->getRootDomain());
555+
auto targetPlatform = swift::targetPlatform(ctx.LangOpts);
556+
if (targetPlatform != PlatformKind::none)
557+
domains.insert(
558+
AvailabilityDomain::forPlatform(targetPlatform).getRootDomain());
559+
560+
auto targetVariantPlatform = swift::targetVariantPlatform(ctx.LangOpts);
561+
if (targetVariantPlatform != PlatformKind::none)
562+
domains.insert(
563+
AvailabilityDomain::forPlatform(targetVariantPlatform).getRootDomain());
560564

561565
return domains;
562566
}

lib/AST/AvailabilityContext.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,8 @@ AvailabilityContext::getAvailabilityRange(AvailabilityDomain domain,
223223
const ASTContext &ctx) const {
224224
DEBUG_ASSERT(domain.supportsContextRefinement());
225225

226-
if (domain.isActiveForTargetPlatform(ctx)) {
226+
if (domain.isActive(ctx) && domain.isPlatform())
227227
return storage->platformRange;
228-
}
229228

230229
for (auto domainInfo : storage->getDomainInfos()) {
231230
if (domain == domainInfo.getDomain() && !domainInfo.isUnavailable())
@@ -289,7 +288,7 @@ void AvailabilityContext::constrainWithAvailabilityRange(
289288
const AvailabilityRange &range, AvailabilityDomain domain,
290289
const ASTContext &ctx) {
291290

292-
if (domain.isActiveForTargetPlatform(ctx)) {
291+
if (domain.isActive(ctx) && domain.isPlatform()) {
293292
constrainWithPlatformRange(range, ctx);
294293
return;
295294
}
@@ -345,7 +344,7 @@ void AvailabilityContext::constrainWithDeclAndPlatformRange(
345344
break;
346345
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
347346
if (auto introducedRange = attr.getIntroducedRange(ctx)) {
348-
if (domain.isActiveForTargetPlatform(ctx)) {
347+
if (domain.isActive(ctx) && domain.isPlatform()) {
349348
isConstrained |= constrainRange(platformRange, *introducedRange);
350349
} else {
351350
declDomainInfos.push_back({domain, *introducedRange});

lib/AST/AvailabilityDomain.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,6 @@
2121

2222
using namespace swift;
2323

24-
std::optional<AvailabilityDomain>
25-
AvailabilityDomain::forTargetPlatform(const ASTContext &ctx) {
26-
auto platform = swift::targetPlatform(ctx.LangOpts);
27-
if (platform == PlatformKind::none)
28-
return std::nullopt;
29-
30-
return forPlatform(platform);
31-
}
32-
33-
std::optional<AvailabilityDomain>
34-
AvailabilityDomain::forTargetVariantPlatform(const ASTContext &ctx) {
35-
auto platform = swift::targetVariantPlatform(ctx.LangOpts);
36-
if (platform == PlatformKind::none)
37-
return std::nullopt;
38-
39-
return forPlatform(platform);
40-
}
41-
4224
std::optional<AvailabilityDomain>
4325
AvailabilityDomain::builtinDomainForString(StringRef string,
4426
const DeclContext *declContext) {
@@ -118,15 +100,6 @@ bool AvailabilityDomain::isActive(const ASTContext &ctx) const {
118100
}
119101
}
120102

121-
bool AvailabilityDomain::isActiveForTargetPlatform(
122-
const ASTContext &ctx) const {
123-
if (isPlatform()) {
124-
if (auto targetDomain = AvailabilityDomain::forTargetPlatform(ctx))
125-
return targetDomain->getRootDomain().contains(*this);
126-
}
127-
return false;
128-
}
129-
130103
static std::optional<llvm::VersionTuple>
131104
getDeploymentVersion(const AvailabilityDomain &domain, const ASTContext &ctx) {
132105
switch (domain.getKind()) {

test/Parse/diagnose_availability_windows.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -target x86_64-unknown-windows-msvc -parse-stdlib
1+
// RUN: %target-typecheck-verify-swift -target x86_64-unknown-windows-msvc -parse-stdlib -verify-additional-prefix no-target-
2+
// RUN: %target-typecheck-verify-swift -target x86_64-unknown-windows8.0-msvc -parse-stdlib
23

34
// expected-note@+2{{'unavailable()' has been explicitly marked unavailable here}}
45
@available(Windows, unavailable, message: "unsupported")
@@ -14,14 +15,30 @@ func introduced_deprecated() {}
1415
introduced_deprecated()
1516
// expected-note@-1 {{add 'if #available' version check}}
1617

18+
@available(Windows 8, *)
19+
func windows8() {}
20+
1721
@available(Windows 10, *)
1822
func windows10() {}
1923

24+
windows8() // expected-no-target-error {{'windows8()' is only available in Windows 8 or newer}}
25+
// expected-no-target-note@-1 {{add 'if #available' version check}}
26+
2027
// expected-error@+1 {{'windows10()' is only available in Windows 10 or newer}}
2128
windows10()
2229
// expected-note@-1 {{add 'if #available' version check}}
2330

2431
func conditional_compilation() {
32+
// expected-note@-1 {{add @available attribute to enclosing global function}}
2533
if #available(Windows 10, *) {
34+
windows10() // OK
35+
} else {
36+
windows10() // expected-error {{'windows10()' is only available in Windows 10 or newer}}
37+
// expected-note@-1 {{add 'if #available' version check}}
2638
}
2739
}
40+
41+
@available(Windows 10, *)
42+
func windows10_caller() {
43+
windows10() // OK
44+
}

unittests/AST/AvailabilityDomainTests.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -150,32 +150,3 @@ TEST_F(AvailabilityDomainLattice, RootDomain) {
150150
EXPECT_EQ(visionOSAppExt.getRootDomain(), iOS);
151151
EXPECT_FALSE(visionOSAppExt.isRoot());
152152
}
153-
154-
TEST(AvailabilityDomain, TargetPlatform) {
155-
using namespace llvm;
156-
157-
struct TargetToPlatformKind {
158-
Triple target;
159-
PlatformKind platformKind;
160-
};
161-
TargetToPlatformKind tests[] = {
162-
{Triple("x86_64", "apple", "macosx10.15"), PlatformKind::macOS},
163-
{Triple("arm64", "apple", "ios13"), PlatformKind::iOS},
164-
{Triple("arm64_32", "apple", "watchos8"), PlatformKind::watchOS},
165-
{Triple("x86_64", "apple", "ios14", "macabi"), PlatformKind::macCatalyst},
166-
{Triple("x86_64", "unknown", "windows", "msvc"), PlatformKind::none},
167-
{Triple("x86_64", "unknown", "linux", "gnu"), PlatformKind::none},
168-
};
169-
170-
for (TargetToPlatformKind test : tests) {
171-
TestContext context{test.target};
172-
auto domain = AvailabilityDomain::forTargetPlatform(context.Ctx);
173-
if (test.platformKind != PlatformKind::none) {
174-
EXPECT_TRUE(domain);
175-
if (domain)
176-
EXPECT_TRUE(domain->getPlatformKind() == test.platformKind);
177-
} else {
178-
EXPECT_FALSE(domain);
179-
}
180-
}
181-
}

0 commit comments

Comments
 (0)