Skip to content

Commit e8eabd7

Browse files
committed
[AST] NFC: Add reentrancy check to associated type anchor walk
This makes compiler crasher 28870 crash faster and reliably instead of recursing off the end of the stack. This reverts: 614cb48
1 parent 550e8cc commit e8eabd7

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

lib/AST/Decl.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,24 +3242,37 @@ AssociatedTypeDecl::getOverriddenDecls() const {
32423242
return assocTypes;
32433243
}
32443244

3245-
AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
3246-
auto overridden = getOverriddenDecls();
3245+
namespace {
3246+
static AssociatedTypeDecl *getAssociatedTypeAnchor(
3247+
const AssociatedTypeDecl *ATD,
3248+
llvm::SmallSet<const AssociatedTypeDecl *, 8> &searched) {
3249+
auto overridden = ATD->getOverriddenDecls();
32473250

32483251
// If this declaration does not override any other declarations, it's
32493252
// the anchor.
3250-
if (overridden.empty()) return const_cast<AssociatedTypeDecl *>(this);
3253+
if (overridden.empty()) return const_cast<AssociatedTypeDecl *>(ATD);
32513254

3252-
// Find the best anchor among the anchors of the overridden decls.
3255+
// Find the best anchor among the anchors of the overridden decls and avoid
3256+
// reentrancy when erroneous cyclic protocols exist.
32533257
AssociatedTypeDecl *bestAnchor = nullptr;
32543258
for (auto assocType : overridden) {
3255-
assert(this != assocType && "AssociatedTypeDecl cannot override itself");
3256-
auto anchor = assocType->getAssociatedTypeAnchor();
3257-
if (!bestAnchor || compare(anchor, bestAnchor) < 0)
3259+
if (!searched.insert(assocType).second)
3260+
continue;
3261+
auto anchor = getAssociatedTypeAnchor(assocType, searched);
3262+
if (!anchor)
3263+
continue;
3264+
if (!bestAnchor || AbstractTypeParamDecl::compare(anchor, bestAnchor) < 0)
32583265
bestAnchor = anchor;
32593266
}
32603267

32613268
return bestAnchor;
32623269
}
3270+
};
3271+
3272+
AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
3273+
llvm::SmallSet<const AssociatedTypeDecl *, 8> searched;
3274+
return ::getAssociatedTypeAnchor(this, searched);
3275+
}
32633276

32643277
EnumDecl::EnumDecl(SourceLoc EnumLoc,
32653278
Identifier Name, SourceLoc NameLoc,

0 commit comments

Comments
 (0)