Merge pull request #79165 from xymus/deser-protect-generic-params

Serialization: Protect `maybeReadGenericParams` against errors
This commit is contained in:
Alexis Laferrière
2025-02-21 17:24:55 -08:00
committed by GitHub
2 changed files with 33 additions and 14 deletions

View File

@@ -1197,7 +1197,8 @@ ModuleFile::getConformanceChecked(ProtocolConformanceID conformanceID) {
}
}
GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
Expected<GenericParamList *>
ModuleFile::maybeReadGenericParams(DeclContext *DC) {
using namespace decls_block;
assert(DC && "need a context for the decls in the list");
@@ -1222,7 +1223,10 @@ GenericParamList *ModuleFile::maybeReadGenericParams(DeclContext *DC) {
ArrayRef<uint64_t> paramIDs;
GenericParamListLayout::readRecord(scratch, paramIDs);
for (DeclID nextParamID : paramIDs) {
auto genericParam = cast<GenericTypeParamDecl>(getDecl(nextParamID));
Decl *nextParam;
UNWRAP(getDeclChecked(nextParamID), nextParam);
auto genericParam = cast<GenericTypeParamDecl>(nextParam);
params.push_back(genericParam);
}
@@ -3427,7 +3431,8 @@ public:
DeclContext *DC;
UNWRAP(MF.getDeclContextChecked(contextID), DC);
auto genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -3586,7 +3591,8 @@ public:
if (declOrOffset.isComplete())
return declOrOffset;
auto genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -3700,7 +3706,8 @@ public:
if (declOrOffset.isComplete())
return declOrOffset;
auto *genericParams = MF.maybeReadGenericParams(parent);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(parent), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -4254,7 +4261,8 @@ public:
// Read generic params before reading the type, because the type may
// reference generic parameters, and we want them to have a dummy
// DeclContext for now.
GenericParamList *genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
auto staticSpelling = getActualStaticSpellingKind(rawStaticSpelling);
if (!staticSpelling.has_value())
@@ -4488,7 +4496,8 @@ public:
if (declOrOffset.isComplete())
return cast<OpaqueTypeDecl>(declOrOffset.get());
auto genericParams = MF.maybeReadGenericParams(declContext);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(declContext), genericParams);
// Create the decl.
auto opaqueDecl = OpaqueTypeDecl::get(
@@ -4689,7 +4698,8 @@ public:
ctx.evaluator.cacheOutput(InheritedProtocolsRequest{proto},
ctx.AllocateCopy(inherited));
auto genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
assert(genericParams && "protocol with no generic parameters?");
ctx.evaluator.cacheOutput(GenericParamListRequest{proto},
std::move(genericParams));
@@ -4884,7 +4894,8 @@ public:
if (declOrOffset.isComplete())
return declOrOffset;
auto genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -4962,7 +4973,8 @@ public:
return DCOrError.takeError();
auto DC = DCOrError.get();
auto genericParams = MF.maybeReadGenericParams(DC);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -5157,7 +5169,8 @@ public:
if (declOrOffset.isComplete())
return declOrOffset;
auto *genericParams = MF.maybeReadGenericParams(parent);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(parent), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;
@@ -5263,7 +5276,12 @@ public:
// Generic parameter lists are written from outermost to innermost.
// Keep reading until we run out of generic parameter lists.
GenericParamList *outerParams = nullptr;
while (auto *genericParams = MF.maybeReadGenericParams(DC)) {
while (true) {
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(DC), genericParams);
if (!genericParams)
break;
genericParams->setOuterParameters(outerParams);
// Set up the DeclContexts for the GenericTypeParamDecls in the list.
@@ -5407,7 +5425,8 @@ public:
if (declOrOffset.isComplete())
return declOrOffset;
auto *genericParams = MF.maybeReadGenericParams(parent);
GenericParamList *genericParams;
UNWRAP(MF.maybeReadGenericParams(parent), genericParams);
if (declOrOffset.isComplete())
return declOrOffset;

View File

@@ -507,7 +507,7 @@ private:
///
/// If the record at the cursor is not a generic param list, returns null
/// without moving the cursor.
GenericParamList *maybeReadGenericParams(DeclContext *DC);
llvm::Expected<GenericParamList *> maybeReadGenericParams(DeclContext *DC);
/// Reads a set of requirements from \c DeclTypeCursor.
void deserializeGenericRequirements(ArrayRef<uint64_t> scratch,