@@ -1476,30 +1476,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
1476
1476
bool swift::extractCompilerFlagsFromInterface (
1477
1477
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
1478
1478
SmallVectorImpl<const char *> &SubArgs,
1479
- std::optional<llvm::Triple> PreferredTarget) {
1479
+ std::optional<llvm::Triple> PreferredTarget, DiagnosticEngine *Diag ) {
1480
1480
auto FlagMatch = getFlagsFromInterfaceFile (buffer, SWIFT_MODULE_FLAGS_KEY);
1481
1481
if (!FlagMatch)
1482
1482
return true ;
1483
1483
llvm::cl::TokenizeGNUCommandLine (*FlagMatch, ArgSaver, SubArgs);
1484
1484
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 ;
1494
1489
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 ()) {
1500
1498
triple.setArch (PreferredTarget->getArch (), PreferredTarget->getSubArch ());
1501
- SubArgs[I] = ArgSaver. save (triple. str ()). data () ;
1499
+ shouldModify = true ;
1502
1500
}
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 ();
1503
1543
}
1504
1544
1505
1545
auto IgnFlagMatch =
0 commit comments