@@ -277,6 +277,18 @@ getInnermostIntroVersion(ArrayRef<Decl*> DeclStack, PlatformKind Platform) {
277
277
return None;
278
278
}
279
279
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
+
280
292
void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious (StringRef name,
281
293
llvm::MachO::SymbolKind kind) {
282
294
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
@@ -323,7 +335,8 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(StringRef name,
323
335
static auto getMinor = [](Optional<unsigned > Minor) {
324
336
return Minor.has_value () ? *Minor : 0 ;
325
337
};
326
- OS << IntroVer->getMajor () << " ." << getMinor (IntroVer->getMinor ()) << " $" ;
338
+ auto verStart = calculateLdPreviousVersionStart (Ctx, *IntroVer);
339
+ OS << verStart.getMajor () << " ." << getMinor (verStart.getMinor ()) << " $" ;
327
340
OS << Ver.Version .getMajor () << " ." << getMinor (Ver.Version .getMinor ()) << " $" ;
328
341
OS << name << " $" ;
329
342
addSymbolInternal (OS.str (), SymbolKind::GlobalSymbol,
0 commit comments