|
57 | 57 | #include "llvm/ADT/SmallString.h"
|
58 | 58 | #include "llvm/ADT/StringSwitch.h"
|
59 | 59 | #include "llvm/Support/Debug.h"
|
| 60 | +#include "swift/AST/DiagnosticsSIL.h" |
60 | 61 | #include "swift/AST/ProtocolConformance.h"
|
61 | 62 | #include "swift/AST/SubstitutionMap.h"
|
62 | 63 | #include "swift/Basic/Assertions.h"
|
@@ -100,12 +101,32 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) {
|
100 | 101 |
|
101 | 102 | /// Deserialize a function and add it to the worklist for processing.
|
102 | 103 | void SILLinkerVisitor::maybeAddFunctionToWorklist(
|
103 |
| - SILFunction *F, SerializedKind_t callerSerializedKind) { |
| 104 | + SILFunction *F, SerializedKind_t callerSerializedKind, SILFunction *caller) { |
104 | 105 | SILLinkage linkage = F->getLinkage();
|
105 |
| - ASSERT((callerSerializedKind == IsNotSerialized || |
| 106 | + |
| 107 | + // Originally this was an assert. But it can happen if the user "re-defines" |
| 108 | + // an existing function with a wrong linkage, e.g. using `@_cdecl`. |
| 109 | + if(!(callerSerializedKind == IsNotSerialized || |
106 | 110 | F->hasValidLinkageForFragileRef(callerSerializedKind) ||
|
107 |
| - hasSharedVisibility(linkage) || F->isExternForwardDeclaration()) && |
108 |
| - "called function has wrong linkage for serialized function"); |
| 111 | + hasSharedVisibility(linkage) || F->isExternForwardDeclaration())) { |
| 112 | + StringRef name = "a serialized function"; |
| 113 | + llvm::SmallVector<char> scratch; |
| 114 | + |
| 115 | + if (caller) { |
| 116 | + name = caller->getName(); |
| 117 | + if (SILDeclRef declRef = caller->getDeclRef()) { |
| 118 | + if (auto *decl = declRef.getDecl()) { |
| 119 | + name = decl->getName().getString(scratch); |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + F->getModule().getASTContext().Diags.diagnose( |
| 124 | + F->getLocation().getSourceLoc(), |
| 125 | + diag::wrong_linkage_for_serialized_function, name); |
| 126 | + hasError = true; |
| 127 | + return; |
| 128 | + } |
| 129 | + |
109 | 130 | if (!F->isExternalDeclaration()) {
|
110 | 131 | // The function is already in the module, so no need to de-serialized it.
|
111 | 132 | // But check if we need to set the IsSerialized flag.
|
@@ -218,19 +239,22 @@ void SILLinkerVisitor::visitPartialApplyInst(PartialApplyInst *PAI) {
|
218 | 239 |
|
219 | 240 | void SILLinkerVisitor::visitFunctionRefInst(FunctionRefInst *FRI) {
|
220 | 241 | maybeAddFunctionToWorklist(FRI->getReferencedFunction(),
|
221 |
| - FRI->getFunction()->getSerializedKind()); |
| 242 | + FRI->getFunction()->getSerializedKind(), |
| 243 | + FRI->getFunction()); |
222 | 244 | }
|
223 | 245 |
|
224 | 246 | void SILLinkerVisitor::visitDynamicFunctionRefInst(
|
225 | 247 | DynamicFunctionRefInst *FRI) {
|
226 | 248 | maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(),
|
227 |
| - FRI->getFunction()->getSerializedKind()); |
| 249 | + FRI->getFunction()->getSerializedKind(), |
| 250 | + FRI->getFunction()); |
228 | 251 | }
|
229 | 252 |
|
230 | 253 | void SILLinkerVisitor::visitPreviousDynamicFunctionRefInst(
|
231 | 254 | PreviousDynamicFunctionRefInst *FRI) {
|
232 | 255 | maybeAddFunctionToWorklist(FRI->getInitiallyReferencedFunction(),
|
233 |
| - FRI->getFunction()->getSerializedKind()); |
| 256 | + FRI->getFunction()->getSerializedKind(), |
| 257 | + FRI->getFunction()); |
234 | 258 | }
|
235 | 259 |
|
236 | 260 | // Eagerly visiting all used conformances leads to a large blowup
|
@@ -470,6 +494,9 @@ void SILLinkerVisitor::process() {
|
470 | 494 | for (auto &BB : *Fn) {
|
471 | 495 | for (auto &I : BB) {
|
472 | 496 | visit(&I);
|
| 497 | + |
| 498 | + if (hasError) |
| 499 | + return; |
473 | 500 | }
|
474 | 501 | }
|
475 | 502 | }
|
|
0 commit comments