Skip to content

Commit 4270bdd

Browse files
authored
Verify that a GenericTypeParamDecl's depth and index are correct (#20445)
Re-applied after fixing a bug in Serialization where the DeclContext wasn't being set correctly for extensions with nested parameters. I was unable to come up with a reduced test case, but the CoreStore project in the source compatibility suite was failing without the Serialization change, and now it isn't.
1 parent aae2c3e commit 4270bdd

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,6 +2738,48 @@ class Verifier : public ASTWalker {
27382738
verifyCheckedBase(nominal);
27392739
}
27402740

2741+
void verifyCheckedAlways(GenericTypeParamDecl *GTPD) {
2742+
PrettyStackTraceDecl debugStack("verifying GenericTypeParamDecl", GTPD);
2743+
2744+
const DeclContext *DC = GTPD->getDeclContext();
2745+
if (!GTPD->getDeclContext()->isInnermostContextGeneric()) {
2746+
Out << "DeclContext of GenericTypeParamDecl does not have "
2747+
"generic params\n";
2748+
abort();
2749+
}
2750+
2751+
GenericParamList *paramList =
2752+
static_cast<const GenericContext *>(DC)->getGenericParams();
2753+
if (!paramList) {
2754+
Out << "DeclContext of GenericTypeParamDecl does not have "
2755+
"generic params\n";
2756+
abort();
2757+
}
2758+
2759+
unsigned currentDepth = paramList->getDepth();
2760+
if (currentDepth < GTPD->getDepth()) {
2761+
Out << "GenericTypeParamDecl has incorrect depth\n";
2762+
abort();
2763+
}
2764+
while (currentDepth > GTPD->getDepth()) {
2765+
paramList = paramList->getOuterParameters();
2766+
--currentDepth;
2767+
}
2768+
assert(paramList && "this is guaranteed by the parameter list's depth");
2769+
2770+
if (paramList->size() <= GTPD->getIndex() ||
2771+
paramList->getParams()[GTPD->getIndex()] != GTPD) {
2772+
if (llvm::is_contained(paramList->getParams(), GTPD))
2773+
Out << "GenericTypeParamDecl has incorrect index\n";
2774+
else
2775+
Out << "GenericTypeParamDecl not found in GenericParamList; "
2776+
"incorrect depth or wrong DeclContext\n";
2777+
abort();
2778+
}
2779+
2780+
verifyCheckedBase(GTPD);
2781+
}
2782+
27412783
void verifyChecked(ExtensionDecl *ext) {
27422784
// Make sure that the protocol conformances are complete.
27432785
for (auto conformance : ext->getLocalConformances()) {

lib/Serialization/Deserialization.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,7 +2702,7 @@ ModuleFile::getDeclCheckedImpl(DeclID DID) {
27022702
index);
27032703

27042704
// Always create GenericTypeParamDecls in the associated module;
2705-
// maybeReadGenericParams() will reparent them.
2705+
// the real context will reparent them.
27062706
auto DC = getAssociatedModule();
27072707
auto genericParam = createDecl<GenericTypeParamDecl>(DC,
27082708
getIdentifier(nameID),
@@ -3964,9 +3964,12 @@ ModuleFile::getDeclCheckedImpl(DeclID DID) {
39643964
// Generic parameter lists are written from outermost to innermost.
39653965
// Keep reading until we run out of generic parameter lists.
39663966
GenericParamList *outerParams = nullptr;
3967-
while (auto *genericParams = maybeReadGenericParams(DC, outerParams))
3967+
while (auto *genericParams = maybeReadGenericParams(DC, outerParams)) {
3968+
// We do this repeatedly to set up the correct DeclContexts for the
3969+
// GenericTypeParamDecls in the list.
3970+
extension->setGenericParams(genericParams);
39683971
outerParams = genericParams;
3969-
extension->setGenericParams(outerParams);
3972+
}
39703973

39713974
configureGenericEnvironment(extension, genericEnvID);
39723975

0 commit comments

Comments
 (0)