Skip to content

Commit 496a43a

Browse files
committed
---
yaml --- r: 345977 b: refs/heads/master c: 2db4021 h: refs/heads/master i: 345975: 78b87b2
1 parent 814e573 commit 496a43a

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 8177651ebe0984f0d81cd1db53cb1c7821570693
2+
refs/heads/master: 2db4021f2ad2f5eb46378285c9b912b16bc5a399
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/AST/Decl.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3245,24 +3245,37 @@ AssociatedTypeDecl::getOverriddenDecls() const {
32453245
return assocTypes;
32463246
}
32473247

3248-
AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
3249-
auto overridden = getOverriddenDecls();
3248+
namespace {
3249+
static AssociatedTypeDecl *getAssociatedTypeAnchor(
3250+
const AssociatedTypeDecl *ATD,
3251+
llvm::SmallSet<const AssociatedTypeDecl *, 8> &searched) {
3252+
auto overridden = ATD->getOverriddenDecls();
32503253

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

3255-
// Find the best anchor among the anchors of the overridden decls.
3258+
// Find the best anchor among the anchors of the overridden decls and avoid
3259+
// reentrancy when erroneous cyclic protocols exist.
32563260
AssociatedTypeDecl *bestAnchor = nullptr;
32573261
for (auto assocType : overridden) {
3258-
assert(this != assocType && "AssociatedTypeDecl cannot override itself");
3259-
auto anchor = assocType->getAssociatedTypeAnchor();
3260-
if (!bestAnchor || compare(anchor, bestAnchor) < 0)
3262+
if (!searched.insert(assocType).second)
3263+
continue;
3264+
auto anchor = getAssociatedTypeAnchor(assocType, searched);
3265+
if (!anchor)
3266+
continue;
3267+
if (!bestAnchor || AbstractTypeParamDecl::compare(anchor, bestAnchor) < 0)
32613268
bestAnchor = anchor;
32623269
}
32633270

32643271
return bestAnchor;
32653272
}
3273+
};
3274+
3275+
AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
3276+
llvm::SmallSet<const AssociatedTypeDecl *, 8> searched;
3277+
return ::getAssociatedTypeAnchor(this, searched);
3278+
}
32663279

32673280
EnumDecl::EnumDecl(SourceLoc EnumLoc,
32683281
Identifier Name, SourceLoc NameLoc,

0 commit comments

Comments
 (0)