@@ -1476,30 +1476,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
14761476bool 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