Skip to content

Commit 89a1f63

Browse files
committed
[CodeCompletion] Make getEquivalentDeclContextFromSourceFile() safe
Gracefully give up finding equivalent decl contxt if something goes wrong. (cherry picked from commit 9b1212b)
1 parent a85e293 commit 89a1f63

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

lib/IDE/CompletionInstance.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ unsigned findIndexInRange(Decl *D, const Range &Decls) {
6464

6565
/// Return the element at \p N in \p Decls .
6666
template <typename Range> Decl *getElementAt(const Range &Decls, unsigned N) {
67-
assert(std::distance(Decls.begin(), Decls.end()) > N);
68-
auto I = Decls.begin();
69-
std::advance(I, N);
70-
return *I;
67+
for (auto I = Decls.begin(), E = Decls.end(); I != E; ++I) {
68+
if (N == 0)
69+
return *I;
70+
--N;
71+
}
72+
return nullptr;
7173
}
7274

7375
/// Find the equivalent \c DeclContext with \p DC from \p SF AST.
@@ -85,6 +87,8 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
8587
SmallVector<unsigned, 4> IndexStack;
8688
do {
8789
auto *D = newDC->getAsDecl();
90+
if (!D)
91+
return nullptr;
8892
auto *parentDC = newDC->getParent();
8993
unsigned N;
9094

@@ -93,10 +97,12 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
9397
// DeclContext -> AbstractStorageDecl -> AccessorDecl
9498
// We need to push the index of the accessor within the accessor list
9599
// of the storage.
96-
auto accessorN =
97-
findIndexInRange(accessor, accessor->getStorage()->getAllAccessors());
100+
auto *storage = accessor->getStorage();
101+
if (!storage)
102+
return nullptr;
103+
auto accessorN = findIndexInRange(accessor, storage->getAllAccessors());
98104
IndexStack.push_back(accessorN);
99-
D = accessor->getStorage();
105+
D = storage;
100106
}
101107

102108
if (auto parentSF = dyn_cast<SourceFile>(parentDC))
@@ -137,7 +143,9 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
137143
D = getElementAt(storage->getAllAccessors(), accessorN);
138144
}
139145

140-
newDC = cast<DeclContext>(D);
146+
newDC = dyn_cast<DeclContext>(D);
147+
if (!newDC)
148+
return nullptr;
141149
} while (!IndexStack.empty());
142150

143151
assert(newDC->getContextKind() == DC->getContextKind());

0 commit comments

Comments
 (0)