@@ -1470,30 +1470,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
14701470bool swift::extractCompilerFlagsFromInterface (
14711471 StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
14721472 SmallVectorImpl<const char *> &SubArgs,
1473- std::optional<llvm::Triple> PreferredTarget) {
1473+ std::optional<llvm::Triple> PreferredTarget, DiagnosticEngine *Diag ) {
14741474 auto FlagMatch = getFlagsFromInterfaceFile (buffer, SWIFT_MODULE_FLAGS_KEY);
14751475 if (!FlagMatch)
14761476 return true ;
14771477 llvm::cl::TokenizeGNUCommandLine (*FlagMatch, ArgSaver, SubArgs);
14781478
1479- // If the target triple parsed from the Swift interface file differs
1480- // only in subarchitecture from the compatible target triple, then
1481- // we have loaded a Swift interface from a different-but-compatible
1482- // architecture slice. Use the compatible subarchitecture.
1483- if (PreferredTarget) {
1484- for (unsigned I = 1 ; I < SubArgs.size (); ++I) {
1485- if (strcmp (SubArgs[I - 1 ], " -target" ) != 0 &&
1486- strcmp (SubArgs[I - 1 ], " -target-variant" ) != 0 )
1487- continue ;
1479+ for (unsigned I = 1 ; I < SubArgs.size (); ++I) {
1480+ if (strcmp (SubArgs[I - 1 ], " -target" ) != 0 &&
1481+ strcmp (SubArgs[I - 1 ], " -target-variant" ) != 0 )
1482+ continue ;
14881483
1489- llvm::Triple triple (SubArgs[I]);
1490- if (triple.getArch () != PreferredTarget->getArch ())
1491- continue ;
1492- if (triple.getSubArch () == PreferredTarget->getSubArch ())
1493- continue ;
1484+ llvm::Triple triple (SubArgs[I]);
1485+ bool shouldModify = false ;
1486+ // If the target triple parsed from the swiftinterface file differs
1487+ // only in subarchitecture from the compatible target triple, then
1488+ // we have loaded a Swift interface from a different-but-compatible
1489+ // architecture slice. Use the compatible subarchitecture.
1490+ if (PreferredTarget && triple.getArch () == PreferredTarget->getArch () &&
1491+ triple.getSubArch () != PreferredTarget->getSubArch ()) {
14941492 triple.setArch (PreferredTarget->getArch (), PreferredTarget->getSubArch ());
1495- SubArgs[I] = ArgSaver. save (triple. str ()). data () ;
1493+ shouldModify = true ;
14961494 }
1495+
1496+ // Diagnose if the version in the target triple parsed from the
1497+ // swiftinterface is invalid for the OS.
1498+ const llvm::VersionTuple originalVer = triple.getOSVersion ();
1499+ bool isValidVersion =
1500+ llvm::Triple::isValidVersionForOS (triple.getOS (), originalVer);
1501+ if (!isValidVersion) {
1502+ if (Diag) {
1503+ Diag->diagnose (SourceLoc (),
1504+ diag::target_os_version_from_textual_interface_invalid,
1505+ triple.str (), interfacePath);
1506+ }
1507+ break ;
1508+ }
1509+
1510+ // Canonicalize the version in the target triple parsed from the
1511+ // swiftinterface.
1512+ llvm::VersionTuple newVer = llvm::Triple::getCanonicalVersionForOS (
1513+ triple.getOS (), originalVer, isValidVersion);
1514+ if (originalVer != newVer) {
1515+ std::string originalOSName = triple.getOSName ().str ();
1516+ std::string originalVerStr = originalVer.getAsString ();
1517+ std::string newVerStr = newVer.getAsString ();
1518+ const int OSNameWithoutVersionLength =
1519+ originalOSName.size () - originalVerStr.size ();
1520+ if (!StringRef (originalOSName).ends_with (originalVerStr) ||
1521+ (OSNameWithoutVersionLength <= 0 )) {
1522+ if (Diag) {
1523+ Diag->diagnose (SourceLoc (),
1524+ diag::map_os_version_from_textual_interface_failed,
1525+ originalVerStr, newVerStr, interfacePath);
1526+ }
1527+ break ;
1528+ }
1529+ llvm::SmallString<64 > buffer (
1530+ originalOSName.substr (0 , OSNameWithoutVersionLength));
1531+ buffer.append (newVerStr);
1532+ triple.setOSName (buffer.str ());
1533+ shouldModify = true ;
1534+ }
1535+ if (shouldModify)
1536+ SubArgs[I] = ArgSaver.save (triple.str ()).data ();
14971537 }
14981538
14991539 auto IgnFlagMatch =
0 commit comments