From 95d5b5da338b517c52cef0d159898201bf790958 Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Fri, 21 Nov 2025 11:47:06 +0100 Subject: [PATCH 1/2] SIL: make `getLinkageString(SILLinkage linkage)` available as general API --- include/swift/SIL/SILLinkage.h | 3 +++ lib/SIL/IR/SILPrinter.cpp | 24 ++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h index ee238d86f8fe4..5f8474340f127 100644 --- a/include/swift/SIL/SILLinkage.h +++ b/include/swift/SIL/SILLinkage.h @@ -421,6 +421,9 @@ inline bool fixmeWitnessHasLinkageThatNeedsToBePublic(SILDeclRef witness, (!hasSharedVisibility(witnessLinkage) || !witness.isSerialized()); } +// Defined in SILPrinter +StringRef getLinkageString(SILLinkage linkage); + } // end swift namespace #endif diff --git a/lib/SIL/IR/SILPrinter.cpp b/lib/SIL/IR/SILPrinter.cpp index 6e2b4fa6a82bc..388de96f91187 100644 --- a/lib/SIL/IR/SILPrinter.cpp +++ b/lib/SIL/IR/SILPrinter.cpp @@ -3505,18 +3505,18 @@ void SILFunction::dump(const char *FileName) const { print(os); } -static StringRef getLinkageString(SILLinkage linkage) { +StringRef swift::getLinkageString(SILLinkage linkage) { switch (linkage) { - case SILLinkage::Public: return "public "; - case SILLinkage::PublicNonABI: return "non_abi "; - case SILLinkage::Package: return "package "; - case SILLinkage::PackageNonABI: return "package_non_abi "; - case SILLinkage::Hidden: return "hidden "; - case SILLinkage::Shared: return "shared "; - case SILLinkage::Private: return "private "; - case SILLinkage::PublicExternal: return "public_external "; - case SILLinkage::PackageExternal: return "package_external "; - case SILLinkage::HiddenExternal: return "hidden_external "; + case SILLinkage::Public: return "public"; + case SILLinkage::PublicNonABI: return "non_abi"; + case SILLinkage::Package: return "package"; + case SILLinkage::PackageNonABI: return "package_non_abi"; + case SILLinkage::Hidden: return "hidden"; + case SILLinkage::Shared: return "shared"; + case SILLinkage::Private: return "private"; + case SILLinkage::PublicExternal: return "public_external"; + case SILLinkage::PackageExternal: return "package_external"; + case SILLinkage::HiddenExternal: return "hidden_external"; } llvm_unreachable("bad linkage"); } @@ -3527,7 +3527,7 @@ static void printLinkage(llvm::raw_ostream &OS, SILLinkage linkage, (!isDefinition && linkage == SILLinkage::DefaultForDeclaration)) return; - OS << getLinkageString(linkage); + OS << getLinkageString(linkage) << ' '; } From 9d02917087248addb2c63425b2a3a25f317d7dcb Mon Sep 17 00:00:00 2001 From: Erik Eckstein Date: Fri, 21 Nov 2025 11:47:46 +0100 Subject: [PATCH 2/2] SIL: make a linkage mismatch during de-serialization a human readable diagnostic Although this error can only happen when tinkering with the stdlib's runtime functions, it's nice to get a readable error message. So far, the compiler just crashed later without a hint to the original problem. --- include/swift/AST/DiagnosticsSIL.def | 4 ++++ lib/SILOptimizer/UtilityPasses/Link.cpp | 23 +++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/swift/AST/DiagnosticsSIL.def b/include/swift/AST/DiagnosticsSIL.def index 90846e4e3fc58..5748c20f71b3f 100644 --- a/include/swift/AST/DiagnosticsSIL.def +++ b/include/swift/AST/DiagnosticsSIL.def @@ -142,6 +142,10 @@ ERROR(deserialize_function_type_mismatch,Fatal, "type mismatch of function '%0', declared as %1 but used in a swift module as %2", (StringRef, Type, Type)) +ERROR(deserialize_function_linkage_mismatch,Fatal, + "linkage mismatch of function '%0', declared as %1 but expected as %2", + (StringRef, StringRef, StringRef)) + ERROR(without_actually_escaping_on_isolated_any,none, "withoutActuallyEscaping is currently unimplemented for '@isolated(any)' " "function values", ()) diff --git a/lib/SILOptimizer/UtilityPasses/Link.cpp b/lib/SILOptimizer/UtilityPasses/Link.cpp index b899595d56d55..2cead51ad9167 100644 --- a/lib/SILOptimizer/UtilityPasses/Link.cpp +++ b/lib/SILOptimizer/UtilityPasses/Link.cpp @@ -10,7 +10,9 @@ // //===----------------------------------------------------------------------===// +#include "swift/AST/DiagnosticsSIL.h" #include "swift/AST/ProtocolConformance.h" +#include "swift/Demangling/Demangle.h" #include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILModule.h" @@ -158,8 +160,25 @@ linkEmbeddedRuntimeFunctionByName(#NAME, EFFECT, StringRef(#CC) == "C_CC"); \ if (auto *Fn = M.lookUpFunction(name, byAsmName)) return Fn; SILFunction *Fn = - M.getSILLoader()->lookupSILFunction(name, Linkage, byAsmName); - if (!Fn) return nullptr; + M.getSILLoader()->lookupSILFunction(name, Linkage,byAsmName); + + if (!Fn) { + SILFunction *fnWithWrongLinkage = + M.getSILLoader()->lookupSILFunction(name, {}, byAsmName); + + if (fnWithWrongLinkage) { + auto fnName = Demangle::demangleSymbolAsString(name, + Demangle::DemangleOptions::SimplifiedUIDemangleOptions()); + auto &diags = getModule()->getASTContext().Diags; + diags.diagnose(fnWithWrongLinkage->getLocation().getSourceLoc(), + diag::deserialize_function_linkage_mismatch, + fnName, getLinkageString(fnWithWrongLinkage->getLinkage()), + getLinkageString(*Linkage)); + diags.flushConsumers(); + exit(1); + } + return nullptr; + } if (M.linkFunction(Fn, LinkMode)) invalidateAnalysis(Fn, SILAnalysis::InvalidationKind::Everything);