Skip to content

Commit a1d4649

Browse files
committed
[clangd] Fix division by zero when computing scores
NameMatch could be a float close to zero, in such cases we were dividing by zero and moreover propogating a "NaN" to clients, which is invalid per JSON. This fixes the issue by only using Quality scores whenever the NameMatch is low, as we do in CodeCompletion ranking. Fixes clangd/clangd#648. Differential Revision: https://reviews.llvm.org/D94755
1 parent f07403e commit a1d4649

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include "llvm/Support/ScopedPrinter.h"
7171
#include <algorithm>
7272
#include <iterator>
73+
#include <limits>
7374

7475
// We log detailed candidate here if you run with -debug-only=codecomplete.
7576
#define DEBUG_TYPE "CodeComplete"
@@ -1655,9 +1656,10 @@ class CodeCompleteFlow {
16551656
evaluateSymbolAndRelevance(Scores.Quality, Scores.Relevance);
16561657
// NameMatch is in fact a multiplier on total score, so rescoring is
16571658
// sound.
1658-
Scores.ExcludingName = Relevance.NameMatch
1659-
? Scores.Total / Relevance.NameMatch
1660-
: Scores.Quality;
1659+
Scores.ExcludingName =
1660+
Relevance.NameMatch > std::numeric_limits<float>::epsilon()
1661+
? Scores.Total / Relevance.NameMatch
1662+
: Scores.Quality;
16611663
return Scores;
16621664

16631665
case RM::DecisionForest:

clang-tools-extra/clangd/FindSymbols.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/Support/FormatVariadic.h"
2626
#include "llvm/Support/Path.h"
2727
#include "llvm/Support/ScopedPrinter.h"
28+
#include <limits>
2829
#include <tuple>
2930

3031
#define DEBUG_TYPE "FindSymbols"
@@ -146,8 +147,9 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
146147
return;
147148
}
148149
Relevance.merge(Sym);
149-
auto Score = evaluateSymbolAndRelevance(Quality.evaluateHeuristics(),
150-
Relevance.evaluateHeuristics());
150+
auto QualScore = Quality.evaluateHeuristics();
151+
auto RelScore = Relevance.evaluateHeuristics();
152+
auto Score = evaluateSymbolAndRelevance(QualScore, RelScore);
151153
dlog("FindSymbols: {0}{1} = {2}\n{3}{4}\n", Sym.Scope, Sym.Name, Score,
152154
Quality, Relevance);
153155

@@ -159,7 +161,9 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
159161
Info.containerName = Scope.str();
160162

161163
// Exposed score excludes fuzzy-match component, for client-side re-ranking.
162-
Info.score = Score / Relevance.NameMatch;
164+
Info.score = Relevance.NameMatch > std::numeric_limits<float>::epsilon()
165+
? Score / Relevance.NameMatch
166+
: QualScore;
163167
Top.push({Score, std::move(Info)});
164168
});
165169
for (auto &R : std::move(Top).items())

0 commit comments

Comments
 (0)