Skip to content

Commit 8b099f0

Browse files
fix: Add visited check to dependent member name lookup (#416)
A customer reported an issue where the number of iterations exceeded 10k. This is likely because of repeatedly checking the same type somehow. I don't have a minimal reproducer for it, but add a hard-coded limit + a visited check to prevent timeouts.
1 parent 203e68f commit 8b099f0

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

indexer/ApproximateNameResolver.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "clang/AST/DeclTemplate.h"
44
#include "clang/AST/DeclarationName.h"
55
#include "clang/AST/Type.h"
6+
#include "llvm/ADT/SmallPtrSet.h"
67
#include "llvm/ADT/SmallVector.h"
78

89
#include "indexer/ApproximateNameResolver.h"
@@ -39,11 +40,26 @@ ApproximateNameResolver::tryResolveMember(
3940
};
4041

4142
llvm::SmallVector<const clang::Type *, 2> typesToLookup;
43+
llvm::SmallPtrSet<const clang::Type *, 2> seen;
4244
typesToLookup.push_back(type);
4345

46+
size_t iterations = 0;
4447
while (!typesToLookup.empty()) {
48+
iterations++;
49+
if (iterations > 10'000) {
50+
spdlog::warn(
51+
"exceeded 10000 iterations in member lookup for '{}' in type '{}'",
52+
declNameInfo.getAsString(), clang::QualType(type, 0).getAsString());
53+
spdlog::info("this is likely a scip-clang bug; please report it at "
54+
"https://github.com/sourcegraph/scip-clang/issues");
55+
break;
56+
}
4557
auto *type = typesToLookup.back();
4658
typesToLookup.pop_back();
59+
if (seen.find(type) != seen.end()) {
60+
continue;
61+
}
62+
seen.insert(type);
4763
auto *cxxRecordDecl = Self::tryFindDeclForType(type);
4864
if (!cxxRecordDecl || !cxxRecordDecl->hasDefinition()) {
4965
continue;

indexer/Indexer.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,19 @@ void TuIndexer::saveTagDecl(const clang::TagDecl &tagDecl) {
729729
stack.push_back(cxxRecordDecl);
730730
}
731731

732+
size_t iterations = 0;
732733
while (!stack.empty()) {
734+
iterations++;
735+
if (iterations > 10'000) {
736+
spdlog::warn(
737+
"visited over 10000 types in inheritance hierarchy for type '{}' at "
738+
"'{}'",
739+
startDecl->getQualifiedNameAsString(),
740+
debug::formatLoc(this->sourceManager, startDecl->getLocation()));
741+
spdlog::info("this is likely a scip-clang bug; please report it at "
742+
"https://github.com/sourcegraph/scip-clang/issues");
743+
break;
744+
}
733745
auto *cxxRecordDecl = stack.back();
734746
stack.pop_back();
735747
if (!cxxRecordDecl || seen.contains(cxxRecordDecl)) {

0 commit comments

Comments
 (0)