Skip to content

Commit 9bf0b6b

Browse files
committed
[SIL Serialization] Print mismatching SILFunction types on error
The crash on `SILFunction type mismatch` provides little information and tends to be difficult to reproduce. Let's print some of the available information and distinguish the two failure sites. I'm not confident all required information is written down so we may need to improve this further in the future. This version still crashes the compiler, we may want a proper type-check to prevent this failure with a clean diagnostic for the example used here. rdar://53821031
1 parent 08af8a6 commit 9bf0b6b

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

lib/SIL/IR/SILType.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,7 +1148,6 @@ std::string SILType::getDebugDescription() const {
11481148
std::string str;
11491149
llvm::raw_string_ostream os(str);
11501150
print(os);
1151-
str.pop_back(); // Remove trailing newline.
11521151
return str;
11531152
}
11541153

lib/Serialization/DeserializationErrors.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,28 @@ class SILEntityError : public llvm::ErrorInfo<SILEntityError> {
442442
}
443443
};
444444

445+
class SILFunctionTypeMismatch : public llvm::ErrorInfo<SILFunctionTypeMismatch> {
446+
friend ErrorInfo;
447+
static const char ID;
448+
void anchor() override;
449+
450+
StringRef name;
451+
std::string descLHS, descRHS;
452+
public:
453+
SILFunctionTypeMismatch(StringRef name, std::string descLHS,
454+
std::string descRHS)
455+
: name(name), descLHS(descLHS), descRHS(descRHS) {}
456+
457+
void log(raw_ostream &OS) const override {
458+
OS << "SILFunction type mismatch for '" << name << "': '";
459+
OS << descLHS << "' != '" << descRHS << "'\n";
460+
}
461+
462+
std::error_code convertToErrorCode() const override {
463+
return llvm::inconvertibleErrorCode();
464+
}
465+
};
466+
445467
// Decl was not deserialized because its attributes did not match the filter.
446468
//
447469
// \sa getDeclChecked

lib/Serialization/DeserializeSIL.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ using namespace llvm::support;
4848

4949
const char SILEntityError::ID = '\0';
5050
void SILEntityError::anchor() {}
51+
const char SILFunctionTypeMismatch::ID = '\0';
52+
void SILFunctionTypeMismatch::anchor() {}
5153

5254
STATISTIC(NumDeserializedFunc, "Number of deserialized SIL functions");
5355

@@ -615,8 +617,13 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
615617

616618
// If we have an existing function, verify that the types match up.
617619
if (fn) {
618-
if (fn->getLoweredType() != ty)
619-
return MF->diagnoseFatal("SILFunction type mismatch");
620+
if (fn->getLoweredType() != ty) {
621+
auto error = llvm::make_error<SILFunctionTypeMismatch>(
622+
name,
623+
fn->getLoweredType().getDebugDescription(),
624+
ty.getDebugDescription());
625+
return MF->diagnoseFatal(std::move(error));
626+
}
620627

621628
fn->setSerialized(IsSerialized_t(isSerialized));
622629

@@ -650,7 +657,7 @@ SILDeserializer::readSILFunctionChecked(DeclID FID, SILFunction *existingFn,
650657
}
651658

652659
if (fn->isDynamicallyReplaceable() != isDynamic)
653-
return MF->diagnoseFatal("SILFunction type mismatch");
660+
return MF->diagnoseFatal("SILFunction dynamic replaceable mismatch");
654661

655662
} else {
656663
// Otherwise, create a new function.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: not --crash %target-swift-frontend -c %s 2>&1 | %FileCheck %s
2+
// CHECK: *** DESERIALIZATION FAILURE ***
3+
// CHECK: SILFunction type mismatch for 'asinf': '$@convention(thin) (Float) -> Float' != '$@convention(c) (Float) -> Float'
4+
5+
// REQUIRES: VENDOR=apple
6+
7+
import Darwin
8+
9+
@_silgen_name("asinf") internal func quux(_ x: Float) -> Float
10+
11+
public func bar(_ x: Float) -> Float {
12+
return quux(x)
13+
}

0 commit comments

Comments
 (0)