Skip to content

Commit f774d4a

Browse files
authored
Merge pull request #82151 from tshortli/rhombicuboctahedron-6.2
[6.2] Upstream support for the Xcode 26 SDKs
2 parents 9df7217 + aa1bce2 commit f774d4a

32 files changed

+571
-149
lines changed

include/swift/AST/AvailabilityDomain.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ class AvailabilityDomain final {
209209
/// version ranges.
210210
bool isVersioned() const;
211211

212+
/// Returns true if the given version is a valid version number for this
213+
/// domain. It is an error to call this on an un-versioned domain.
214+
bool isVersionValid(const llvm::VersionTuple &version) const;
215+
212216
/// Returns true if availability of the domain can be refined using
213217
/// `@available` attributes and `if #available` queries. If not, then the
214218
/// domain's availability is fixed by compilation settings. For example,

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,14 @@ ERROR(serialization_failed,none,
864864
WARNING(can_import_invalid_swiftmodule,none,
865865
"canImport() evaluated to false due to invalid swiftmodule: %0", (StringRef))
866866

867+
ERROR(map_os_version_from_textual_interface_failed,none,
868+
"failed to map OS version from %0 to %1 in %2",
869+
(StringRef, StringRef, StringRef))
870+
871+
ERROR(target_os_version_from_textual_interface_invalid,none,
872+
"invalid target triple %0 in %1",
873+
(StringRef, StringRef))
874+
867875
ERROR(serialization_load_failed,Fatal,
868876
"failed to load module '%0'", (StringRef))
869877
ERROR(module_interface_build_failed,Fatal,
@@ -6852,6 +6860,9 @@ GROUPED_ERROR(availability_suggest_platform_name,
68526860
(Identifier, StringRef))
68536861
WARNING(availability_unsupported_version_number, none,
68546862
"'%0' is not a supported version number", (llvm::VersionTuple))
6863+
WARNING(availability_invalid_version_number_for_domain, none,
6864+
"'%0' is not a valid version number for %1",
6865+
(llvm::VersionTuple, AvailabilityDomain))
68556866

68566867
WARNING(attr_availability_expected_deprecated_version, none,
68576868
"expected version number with 'deprecated' in '%0' attribute for %1",

include/swift/AST/PlatformKind.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Config.h"
2222
#include "llvm/ADT/StringRef.h"
2323
#include "llvm/Support/VersionTuple.h"
24+
#include "llvm/TargetParser/Triple.h"
2425
#include <optional>
2526

2627
namespace swift {
@@ -91,6 +92,10 @@ PlatformKind targetVariantPlatform(const LangOptions &LangOpts);
9192
/// an explicit attribute for the child.
9293
bool inheritsAvailabilityFromPlatform(PlatformKind Child, PlatformKind Parent);
9394

95+
/// Returns the LLVM triple OS type for the given platform, if there is one.
96+
std::optional<llvm::Triple::OSType>
97+
tripleOSTypeForPlatform(PlatformKind platform);
98+
9499
llvm::VersionTuple canonicalizePlatformVersion(
95100
PlatformKind platform, const llvm::VersionTuple &version);
96101

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,8 @@ class SerializedASTFile final : public LoadedFile {
580580
bool extractCompilerFlagsFromInterface(
581581
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
582582
SmallVectorImpl<const char *> &SubArgs,
583-
std::optional<llvm::Triple> PreferredTarget = std::nullopt);
583+
std::optional<llvm::Triple> PreferredTarget = std::nullopt,
584+
DiagnosticEngine *diagEngine = nullptr);
584585

585586
/// Extract the user module version number from an interface file.
586587
llvm::VersionTuple extractUserModuleVersionFromInterface(StringRef moduleInterfacePath);

lib/AST/Attr.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,16 +2360,13 @@ static StringRef getLinkerModuleName(StringRef OriginalModuleName) {
23602360
}
23612361

23622362
OriginallyDefinedInAttr::OriginallyDefinedInAttr(
2363-
SourceLoc AtLoc, SourceRange Range,
2364-
StringRef OriginalModuleName,
2365-
PlatformKind Platform,
2366-
const llvm::VersionTuple MovedVersion, bool Implicit)
2367-
: DeclAttribute(DeclAttrKind::OriginallyDefinedIn, AtLoc, Range,
2368-
Implicit),
2369-
ManglingModuleName(getManglingModuleName(OriginalModuleName)),
2370-
LinkerModuleName(getLinkerModuleName(OriginalModuleName)),
2371-
Platform(Platform),
2372-
MovedVersion(MovedVersion) {}
2363+
SourceLoc AtLoc, SourceRange Range, StringRef OriginalModuleName,
2364+
PlatformKind Platform, const llvm::VersionTuple MovedVersion, bool Implicit)
2365+
: DeclAttribute(DeclAttrKind::OriginallyDefinedIn, AtLoc, Range, Implicit),
2366+
ManglingModuleName(getManglingModuleName(OriginalModuleName)),
2367+
LinkerModuleName(getLinkerModuleName(OriginalModuleName)),
2368+
Platform(Platform),
2369+
MovedVersion(canonicalizePlatformVersion(Platform, MovedVersion)) {}
23732370

23742371
std::optional<OriginallyDefinedInAttr::ActiveVersion>
23752372
OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const {

lib/AST/Availability.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,14 +832,27 @@ SemanticAvailableAttrRequest::evaluate(swift::Evaluator &evaluator,
832832

833833
auto checkVersion = [&](std::optional<llvm::VersionTuple> version,
834834
SourceRange sourceRange) {
835-
if (version && !VersionRange::isValidVersion(*version)) {
835+
if (!version)
836+
return false;
837+
838+
if (!VersionRange::isValidVersion(*version)) {
836839
diags
837840
.diagnose(attrLoc, diag::availability_unsupported_version_number,
838841
*version)
839842
.highlight(sourceRange);
840843
return true;
841844
}
842845

846+
// Warn if the version is not a valid one for the domain. For example, macOS
847+
// 17 will never exist.
848+
if (domain->isVersioned() && !domain->isVersionValid(*version)) {
849+
diags
850+
.diagnose(attrLoc,
851+
diag::availability_invalid_version_number_for_domain,
852+
*version, *domain)
853+
.highlight(sourceRange);
854+
}
855+
843856
return false;
844857
};
845858

lib/AST/AvailabilityDomain.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,26 @@ bool AvailabilityDomain::isVersioned() const {
109109
}
110110
}
111111

112+
bool AvailabilityDomain::isVersionValid(
113+
const llvm::VersionTuple &version) const {
114+
ASSERT(isVersioned());
115+
116+
switch (getKind()) {
117+
case Kind::Universal:
118+
case Kind::Embedded:
119+
llvm_unreachable("unexpected domain kind");
120+
case Kind::SwiftLanguage:
121+
case Kind::PackageDescription:
122+
return true;
123+
case Kind::Platform:
124+
if (auto osType = tripleOSTypeForPlatform(getPlatformKind()))
125+
return llvm::Triple::isValidVersionForOS(*osType, version);
126+
return true;
127+
case Kind::Custom:
128+
return true;
129+
}
130+
}
131+
112132
bool AvailabilityDomain::supportsContextRefinement() const {
113133
switch (getKind()) {
114134
case Kind::Universal:

lib/AST/PlatformKind.cpp

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,43 @@ bool swift::inheritsAvailabilityFromPlatform(PlatformKind Child,
263263
return false;
264264
}
265265

266-
llvm::VersionTuple swift::canonicalizePlatformVersion(
267-
PlatformKind platform, const llvm::VersionTuple &version) {
268-
269-
// Canonicalize macOS version for macOS Big Sur to treat
270-
// 10.16 as 11.0.
271-
if (platform == PlatformKind::macOS ||
272-
platform == PlatformKind::macOSApplicationExtension) {
273-
return llvm::Triple::getCanonicalVersionForOS(llvm::Triple::MacOSX,
274-
version);
266+
std::optional<llvm::Triple::OSType>
267+
swift::tripleOSTypeForPlatform(PlatformKind platform) {
268+
switch (platform) {
269+
case PlatformKind::macOS:
270+
case PlatformKind::macOSApplicationExtension:
271+
return llvm::Triple::MacOSX;
272+
case PlatformKind::iOS:
273+
case PlatformKind::iOSApplicationExtension:
274+
case PlatformKind::macCatalyst:
275+
case PlatformKind::macCatalystApplicationExtension:
276+
return llvm::Triple::IOS;
277+
case PlatformKind::tvOS:
278+
case PlatformKind::tvOSApplicationExtension:
279+
return llvm::Triple::TvOS;
280+
case PlatformKind::watchOS:
281+
case PlatformKind::watchOSApplicationExtension:
282+
return llvm::Triple::WatchOS;
283+
case PlatformKind::visionOS:
284+
case PlatformKind::visionOSApplicationExtension:
285+
return llvm::Triple::XROS;
286+
case PlatformKind::OpenBSD:
287+
return llvm::Triple::OpenBSD;
288+
case PlatformKind::Windows:
289+
return llvm::Triple::Win32;
290+
case PlatformKind::none:
291+
return std::nullopt;
292+
}
293+
llvm_unreachable("bad PlatformKind");
294+
}
295+
296+
llvm::VersionTuple
297+
swift::canonicalizePlatformVersion(PlatformKind platform,
298+
const llvm::VersionTuple &version) {
299+
if (auto osType = tripleOSTypeForPlatform(platform)) {
300+
bool isInValidRange = llvm::Triple::isValidVersionForOS(*osType, version);
301+
return llvm::Triple::getCanonicalVersionForOS(*osType, version,
302+
isInValidRange);
275303
}
276304

277305
return version;

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ static bool readSwiftInterfaceVersionAndArgs(
15471547

15481548
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver,
15491549
interfaceInfo.Arguments,
1550-
preferredTarget)) {
1550+
preferredTarget, &Diags)) {
15511551
InterfaceSubContextDelegateImpl::diagnose(
15521552
interfacePath, diagnosticLoc, SM, &Diags,
15531553
diag::error_extracting_version_from_module_interface);

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,30 +1476,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
14761476
bool swift::extractCompilerFlagsFromInterface(
14771477
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
14781478
SmallVectorImpl<const char *> &SubArgs,
1479-
std::optional<llvm::Triple> PreferredTarget) {
1479+
std::optional<llvm::Triple> PreferredTarget, DiagnosticEngine *Diag) {
14801480
auto FlagMatch = getFlagsFromInterfaceFile(buffer, SWIFT_MODULE_FLAGS_KEY);
14811481
if (!FlagMatch)
14821482
return true;
14831483
llvm::cl::TokenizeGNUCommandLine(*FlagMatch, ArgSaver, SubArgs);
14841484

1485-
// If the target triple parsed from the Swift interface file differs
1486-
// only in subarchitecture from the compatible target triple, then
1487-
// we have loaded a Swift interface from a different-but-compatible
1488-
// architecture slice. Use the compatible subarchitecture.
1489-
if (PreferredTarget) {
1490-
for (unsigned I = 1; I < SubArgs.size(); ++I) {
1491-
if (strcmp(SubArgs[I - 1], "-target") != 0 &&
1492-
strcmp(SubArgs[I - 1], "-target-variant") != 0)
1493-
continue;
1485+
for (unsigned I = 1; I < SubArgs.size(); ++I) {
1486+
if (strcmp(SubArgs[I - 1], "-target") != 0 &&
1487+
strcmp(SubArgs[I - 1], "-target-variant") != 0)
1488+
continue;
14941489

1495-
llvm::Triple triple(SubArgs[I]);
1496-
if (triple.getArch() != PreferredTarget->getArch())
1497-
continue;
1498-
if (triple.getSubArch() == PreferredTarget->getSubArch())
1499-
continue;
1490+
llvm::Triple triple(SubArgs[I]);
1491+
bool shouldModify = false;
1492+
// If the target triple parsed from the swiftinterface file differs
1493+
// only in subarchitecture from the compatible target triple, then
1494+
// we have loaded a Swift interface from a different-but-compatible
1495+
// architecture slice. Use the compatible subarchitecture.
1496+
if (PreferredTarget && triple.getArch() == PreferredTarget->getArch() &&
1497+
triple.getSubArch() != PreferredTarget->getSubArch()) {
15001498
triple.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
1501-
SubArgs[I] = ArgSaver.save(triple.str()).data();
1499+
shouldModify = true;
15021500
}
1501+
1502+
// Diagnose if the version in the target triple parsed from the
1503+
// swiftinterface is invalid for the OS.
1504+
const llvm::VersionTuple originalVer = triple.getOSVersion();
1505+
bool isValidVersion =
1506+
llvm::Triple::isValidVersionForOS(triple.getOS(), originalVer);
1507+
if (!isValidVersion) {
1508+
if (Diag) {
1509+
Diag->diagnose(SourceLoc(),
1510+
diag::target_os_version_from_textual_interface_invalid,
1511+
triple.str(), interfacePath);
1512+
}
1513+
break;
1514+
}
1515+
1516+
// Canonicalize the version in the target triple parsed from the
1517+
// swiftinterface.
1518+
llvm::VersionTuple newVer = llvm::Triple::getCanonicalVersionForOS(
1519+
triple.getOS(), originalVer, isValidVersion);
1520+
if (originalVer != newVer) {
1521+
std::string originalOSName = triple.getOSName().str();
1522+
std::string originalVerStr = originalVer.getAsString();
1523+
std::string newVerStr = newVer.getAsString();
1524+
const int OSNameWithoutVersionLength =
1525+
originalOSName.size() - originalVerStr.size();
1526+
if (!StringRef(originalOSName).ends_with(originalVerStr) ||
1527+
(OSNameWithoutVersionLength <= 0)) {
1528+
if (Diag) {
1529+
Diag->diagnose(SourceLoc(),
1530+
diag::map_os_version_from_textual_interface_failed,
1531+
originalVerStr, newVerStr, interfacePath);
1532+
}
1533+
break;
1534+
}
1535+
llvm::SmallString<64> buffer(
1536+
originalOSName.substr(0, OSNameWithoutVersionLength));
1537+
buffer.append(newVerStr);
1538+
triple.setOSName(buffer.str());
1539+
shouldModify = true;
1540+
}
1541+
if (shouldModify)
1542+
SubArgs[I] = ArgSaver.save(triple.str()).data();
15031543
}
15041544

15051545
auto IgnFlagMatch =

test/ClangImporter/Inputs/custom-modules/MacOSVersionCanonicalization.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,20 @@ void FunctionIntroducedIn10_16();
44
__attribute__((availability(macosx,introduced=11.0)))
55
void FunctionIntroducedIn11_0();
66

7+
__attribute__((availability(macosx,introduced=16.0)))
8+
void FunctionIntroducedIn16_0();
9+
10+
__attribute__((availability(macosx,introduced=26.0)))
11+
void FunctionIntroducedIn26_0();
12+
713
__attribute__((availability(macosx_app_extension,introduced=10.16)))
814
void FunctionIntroducedIn10_16AppExt();
915

1016
__attribute__((availability(macosx_app_extension,introduced=11.0)))
1117
void FunctionIntroducedIn11_0AppExt();
18+
19+
__attribute__((availability(macosx_app_extension,introduced=16.0)))
20+
void FunctionIntroducedIn16_0AppExt();
21+
22+
__attribute__((availability(macosx_app_extension,introduced=26.0)))
23+
void FunctionIntroducedIn26_0AppExt();

test/ClangImporter/availability_macosx_canonical_versions.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ FunctionIntroducedIn10_16()
1111
FunctionIntroducedIn11_0()
1212
// expected-error@-1 {{'FunctionIntroducedIn11_0()' is only available in macOS 11.0 or newer}}
1313
// expected-note@-2 {{add 'if #available' version check}}
14+
15+
FunctionIntroducedIn16_0()
16+
// expected-error@-1 {{'FunctionIntroducedIn16_0()' is only available in macOS 26.0 or newer}}
17+
// expected-note@-2 {{add 'if #available' version check}}
18+
19+
FunctionIntroducedIn26_0()
20+
// expected-error@-1 {{'FunctionIntroducedIn26_0()' is only available in macOS 26.0 or newer}}
21+
// expected-note@-2 {{add 'if #available' version check}}

test/ClangImporter/availability_macosx_canonical_versions_appext.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ FunctionIntroducedIn10_16AppExt()
1111
FunctionIntroducedIn11_0AppExt()
1212
// expected-error@-1 {{'FunctionIntroducedIn11_0AppExt()' is only available in application extensions for macOS 11.0 or newer}}
1313
// expected-note@-2 {{add 'if #available' version check}}
14+
15+
FunctionIntroducedIn16_0AppExt()
16+
// expected-error@-1 {{'FunctionIntroducedIn16_0AppExt()' is only available in application extensions for macOS 26.0 or newer}}
17+
// expected-note@-2 {{add 'if #available' version check}}
18+
19+
FunctionIntroducedIn26_0AppExt()
20+
// expected-error@-1 {{'FunctionIntroducedIn26_0AppExt()' is only available in application extensions for macOS 26.0 or newer}}
21+
// expected-note@-2 {{add 'if #available' version check}}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck %s
3+
// RUN: %target-swift-ide-test -skip-deinit=false -print-ast-typechecked -source-filename %s -function-definitions=false -prefer-type-repr=false -print-implicit-attrs=true > %t.printed.txt
4+
// RUN: %FileCheck %s -check-prefix=PASS_COMMON -strict-whitespace < %t.printed.txt
5+
6+
@available(iOS 10.16, OSX 10.16, *)
7+
func introduced10_16() {}
8+
// PASS_COMMON: {{^}}@available(iOS 10.16, macOS 11.0, *){{$}}
9+
// PASS_COMMON-NEXT: {{^}}func introduced10_16(){{$}}
10+
11+
@available(macOS 16.0, iOS 19.0, macCatalyst 19.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *)
12+
func introducedInVersionsMappingTo26_0() {}
13+
// FIXME: visionOS and macCatalyst are missing
14+
// PASS_COMMON: {{^}}@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *){{$}}
15+
// PASS_COMMON-NEXT: {{^}}func introducedInVersionsMappingTo26_0(){{$}}
16+
17+
@available(macOS 18.0, iOS 21.0, macCatalyst 21.0, watchOS 14.0, tvOS 21.0, visionOS 5.0, *)
18+
func introducedInVersionsMappingTo28_0() {}
19+
// FIXME: visionOS and macCatalyst are missing
20+
// PASS_COMMON: {{^}}@available(macOS 28.0, iOS 28.0, watchOS 28.0, tvOS 28.0, *){{$}}
21+
// PASS_COMMON-NEXT: {{^}}func introducedInVersionsMappingTo28_0(){{$}}

test/IDE/print_ast_tc_decls_macosx_canonical_versions.swift

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/IRGen/osx-targets.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
// CHECK: target triple = "{{.*}}-apple-macosx{{[0-9][0-9]}}.
88
// CHECK-SPECIFIC-MAC-10-X: target triple = "{{.*}}-apple-macosx10.51.0"
9-
// CHECK-DARWIN-OVER-11: target triple = "{{.*}}-apple-macosx46.0.0"
9+
// CHECK-DARWIN-OVER-11: target triple = "{{.*}}-apple-macosx56.0.0"
1010

1111
public func anchor() {}
1212
anchor()

0 commit comments

Comments
 (0)