Skip to content

Commit 294b5d0

Browse files
committed
[Serialization] Raise an error (to recover from) when reading an unsafe decl
Intro UnsafeDeserializationError and instanciate it when attempting to deserialize a decl marked as unsafe by a DESERIALIZATION_SAFETY record.
1 parent 2c508d9 commit 294b5d0

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ const char DeclAttributesDidNotMatch::ID = '\0';
155155
void DeclAttributesDidNotMatch::anchor() {}
156156
const char InvalidRecordKindError::ID = '\0';
157157
void InvalidRecordKindError::anchor() {}
158+
const char UnsafeDeserializationError::ID = '\0';
159+
void UnsafeDeserializationError::anchor() {}
158160

159161
/// Skips a single record in the bitstream.
160162
///
@@ -5414,6 +5416,14 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
54145416
} else if (recordID == decls_block::DESERIALIZATION_SAFETY) {
54155417
IdentifierID declID;
54165418
decls_block::DeserializationSafetyLayout::readRecord(scratch, declID);
5419+
5420+
if (MF.getResilienceStrategy() == ResilienceStrategy::Resilient &&
5421+
MF.getContext().LangOpts.EnableDeserializationSafety) {
5422+
auto name = MF.getIdentifier(declID);
5423+
LLVM_DEBUG(llvm::dbgs() << "Skipping unsafe deserialization: '"
5424+
<< name << "'\n");
5425+
return llvm::make_error<UnsafeDeserializationError>(name);
5426+
}
54175427
} else {
54185428
return llvm::Error::success();
54195429
}

lib/Serialization/DeserializationErrors.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,27 @@ class InvalidRecordKindError :
494494
}
495495
};
496496

497+
// Decl was not deserialized because it's an internal detail maked as unsafe
498+
// at serialization.
499+
class UnsafeDeserializationError : public llvm::ErrorInfo<UnsafeDeserializationError, DeclDeserializationError> {
500+
friend ErrorInfo;
501+
static const char ID;
502+
void anchor() override;
503+
504+
public:
505+
UnsafeDeserializationError(Identifier name) {
506+
this->name = name;
507+
}
508+
509+
void log(raw_ostream &OS) const override {
510+
OS << "Decl '" << name << "' is unsafe to deserialize";
511+
}
512+
513+
std::error_code convertToErrorCode() const override {
514+
return llvm::inconvertibleErrorCode();
515+
}
516+
};
517+
497518
LLVM_NODISCARD
498519
static inline std::unique_ptr<llvm::ErrorInfoBase>
499520
takeErrorInfo(llvm::Error error) {

0 commit comments

Comments
 (0)