@@ -1470,30 +1470,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
1470
1470
bool swift::extractCompilerFlagsFromInterface (
1471
1471
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
1472
1472
SmallVectorImpl<const char *> &SubArgs,
1473
- std::optional<llvm::Triple> PreferredTarget) {
1473
+ std::optional<llvm::Triple> PreferredTarget, DiagnosticEngine *Diag ) {
1474
1474
auto FlagMatch = getFlagsFromInterfaceFile (buffer, SWIFT_MODULE_FLAGS_KEY);
1475
1475
if (!FlagMatch)
1476
1476
return true ;
1477
1477
llvm::cl::TokenizeGNUCommandLine (*FlagMatch, ArgSaver, SubArgs);
1478
1478
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 ;
1488
1483
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 ()) {
1494
1492
triple.setArch (PreferredTarget->getArch (), PreferredTarget->getSubArch ());
1495
- SubArgs[I] = ArgSaver. save (triple. str ()). data () ;
1493
+ shouldModify = true ;
1496
1494
}
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 ();
1497
1537
}
1498
1538
1499
1539
auto IgnFlagMatch =
0 commit comments