@@ -277,6 +277,18 @@ getInnermostIntroVersion(ArrayRef<Decl*> DeclStack, PlatformKind Platform) {
277277 return None;
278278}
279279
280+ // / Using the introducing version of a symbol as the start version to redirect
281+ // / linkage path isn't sufficient. This is because the executable can be deployed
282+ // / to OS versions that were before the symbol was introduced. When that happens,
283+ // / strictly using the introductory version can lead to NOT redirecting.
284+ static llvm::VersionTuple calculateLdPreviousVersionStart (ASTContext &ctx,
285+ llvm::VersionTuple introVer) {
286+ auto minDep = ctx.LangOpts .getMinPlatformVersion ();
287+ if (minDep < introVer)
288+ return llvm::VersionTuple (1 , 0 );
289+ return introVer;
290+ }
291+
280292void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious (StringRef name,
281293 llvm::MachO::SymbolKind kind) {
282294 if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
@@ -323,7 +335,8 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(StringRef name,
323335 static auto getMinor = [](Optional<unsigned > Minor) {
324336 return Minor.has_value () ? *Minor : 0 ;
325337 };
326- OS << IntroVer->getMajor () << " ." << getMinor (IntroVer->getMinor ()) << " $" ;
338+ auto verStart = calculateLdPreviousVersionStart (Ctx, *IntroVer);
339+ OS << verStart.getMajor () << " ." << getMinor (verStart.getMinor ()) << " $" ;
327340 OS << Ver.Version .getMajor () << " ." << getMinor (Ver.Version .getMinor ()) << " $" ;
328341 OS << name << " $" ;
329342 addSymbolInternal (OS.str (), SymbolKind::GlobalSymbol,
0 commit comments