Skip to content

[WIP] SIL serialization recovery for instructions #17570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 40 additions & 43 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,6 @@ void TypeError::anchor() {}
const char ExtensionError::ID = '\0';
void ExtensionError::anchor() {}

LLVM_NODISCARD
static std::unique_ptr<llvm::ErrorInfoBase> takeErrorInfo(llvm::Error error) {
std::unique_ptr<llvm::ErrorInfoBase> result;
llvm::handleAllErrors(std::move(error),
[&](std::unique_ptr<llvm::ErrorInfoBase> info) {
result = std::move(info);
});
return result;
}


/// Skips a single record in the bitstream.
///
/// Returns true if the next entry is a record of type \p recordKind.
Expand Down Expand Up @@ -4756,27 +4745,42 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
}

auto processParameter = [&](TypeID typeID, uint64_t rawConvention)
-> Optional<SILParameterInfo> {
-> llvm::Expected<SILParameterInfo> {
auto convention = getActualParameterConvention(rawConvention);
auto type = getType(typeID);
if (!convention || !type) return None;
return SILParameterInfo(type->getCanonicalType(), *convention);
if (!convention) {
error();
llvm_unreachable("an error is a fatal exit at this point");
}
auto type = getTypeChecked(typeID);
if (!type)
return type.takeError();
return SILParameterInfo(type.get()->getCanonicalType(), *convention);
};

auto processYield = [&](TypeID typeID, uint64_t rawConvention)
-> Optional<SILYieldInfo> {
-> llvm::Expected<SILYieldInfo> {
auto convention = getActualParameterConvention(rawConvention);
auto type = getType(typeID);
if (!convention || !type) return None;
return SILYieldInfo(type->getCanonicalType(), *convention);
if (!convention) {
error();
llvm_unreachable("an error is a fatal exit at this point");
}
auto type = getTypeChecked(typeID);
if (!type)
return type.takeError();
return SILYieldInfo(type.get()->getCanonicalType(), *convention);
};

auto processResult = [&](TypeID typeID, uint64_t rawConvention)
-> Optional<SILResultInfo> {
-> llvm::Expected<SILResultInfo> {
auto convention = getActualResultConvention(rawConvention);
auto type = getType(typeID);
if (!convention || !type) return None;
return SILResultInfo(type->getCanonicalType(), *convention);
if (!convention) {
error();
llvm_unreachable("an error is a fatal exit at this point");
}
auto type = getTypeChecked(typeID);
if (!type)
return type.takeError();
return SILResultInfo(type.get()->getCanonicalType(), *convention);
};

// Bounds check. FIXME: overflow
Expand All @@ -4795,11 +4799,9 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
auto typeID = variableData[nextVariableDataIndex++];
auto rawConvention = variableData[nextVariableDataIndex++];
auto param = processParameter(typeID, rawConvention);
if (!param) {
error();
return nullptr;
}
allParams.push_back(*param);
if (!param)
return param.takeError();
allParams.push_back(param.get());
}

// Process the yields.
Expand All @@ -4809,11 +4811,9 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
auto typeID = variableData[nextVariableDataIndex++];
auto rawConvention = variableData[nextVariableDataIndex++];
auto yield = processYield(typeID, rawConvention);
if (!yield) {
error();
return nullptr;
}
allYields.push_back(*yield);
if (!yield)
return yield.takeError();
allYields.push_back(yield.get());
}

// Process the results.
Expand All @@ -4823,23 +4823,20 @@ Expected<Type> ModuleFile::getTypeChecked(TypeID TID) {
auto typeID = variableData[nextVariableDataIndex++];
auto rawConvention = variableData[nextVariableDataIndex++];
auto result = processResult(typeID, rawConvention);
if (!result) {
error();
return nullptr;
}
allResults.push_back(*result);
if (!result)
return result.takeError();
allResults.push_back(result.get());
}

// Process the error result.
Optional<SILResultInfo> errorResult;
if (hasErrorResult) {
auto typeID = variableData[nextVariableDataIndex++];
auto rawConvention = variableData[nextVariableDataIndex++];
errorResult = processResult(typeID, rawConvention);
if (!errorResult) {
error();
return nullptr;
}
auto maybeErrorResult = processResult(typeID, rawConvention);
if (!maybeErrorResult)
return maybeErrorResult.takeError();
errorResult = maybeErrorResult.get();
}

Optional<ProtocolConformanceRef> witnessMethodConformance;
Expand Down
35 changes: 35 additions & 0 deletions lib/Serialization/DeserializationErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,41 @@ class ExtensionError : public llvm::ErrorInfo<ExtensionError> {
}
};

class SILEntityError : public llvm::ErrorInfo<SILEntityError> {
friend ErrorInfo;
static const char ID;
void anchor() override;

std::unique_ptr<ErrorInfoBase> underlyingReason;
StringRef name;
public:
SILEntityError(StringRef name, std::unique_ptr<ErrorInfoBase> reason)
: underlyingReason(std::move(reason)), name(name) {}

void log(raw_ostream &OS) const override {
OS << "could not deserialize SIL entity '" << name << "'";
if (underlyingReason) {
OS << ": ";
underlyingReason->log(OS);
}
}

std::error_code convertToErrorCode() const override {
return llvm::inconvertibleErrorCode();
}
};

LLVM_NODISCARD
static inline std::unique_ptr<llvm::ErrorInfoBase>
takeErrorInfo(llvm::Error error) {
std::unique_ptr<llvm::ErrorInfoBase> result;
llvm::handleAllErrors(std::move(error),
[&](std::unique_ptr<llvm::ErrorInfoBase> info) {
result = std::move(info);
});
return result;
}

class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry {
const char *Action;
const ModuleFile &MF;
Expand Down
Loading