Skip to content

Commit aa1bce2

Browse files
committed
ModuleInterface: Canonicalize OS version numbers in loaded swiftinterfaces.
1 parent 6882649 commit aa1bce2

File tree

4 files changed

+67
-18
lines changed

4 files changed

+67
-18
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 8 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,

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/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 =

0 commit comments

Comments
 (0)