@@ -96,7 +96,8 @@ bool locationInRange(SourceLocation L, CharSourceRange R,
96
96
97
97
// Clang diags have a location (shown as ^) and 0 or more ranges (~~~~).
98
98
// LSP needs a single range.
99
- Range diagnosticRange (const clang::Diagnostic &D, const LangOptions &L) {
99
+ std::optional<Range> diagnosticRange (const clang::Diagnostic &D,
100
+ const LangOptions &L) {
100
101
auto &M = D.getSourceManager ();
101
102
auto PatchedRange = [&M](CharSourceRange &R) {
102
103
R.setBegin (translatePreamblePatchLocation (R.getBegin (), M));
@@ -115,13 +116,18 @@ Range diagnosticRange(const clang::Diagnostic &D, const LangOptions &L) {
115
116
if (locationInRange (Loc, R, M))
116
117
return halfOpenToRange (M, PatchedRange (R));
117
118
}
119
+ // Source locations from stale preambles might become OOB.
120
+ // FIXME: These diagnostics might point to wrong locations even when they're
121
+ // not OOB.
122
+ auto [FID, Offset] = M.getDecomposedLoc (Loc);
123
+ if (Offset > M.getBufferData (FID).size ())
124
+ return std::nullopt;
118
125
// If the token at the location is not a comment, we use the token.
119
126
// If we can't get the token at the location, fall back to using the location
120
127
auto R = CharSourceRange::getCharRange (Loc);
121
128
Token Tok;
122
- if (!Lexer::getRawToken (Loc, Tok, M, L, true ) && Tok.isNot (tok::comment)) {
129
+ if (!Lexer::getRawToken (Loc, Tok, M, L, true ) && Tok.isNot (tok::comment))
123
130
R = CharSourceRange::getTokenRange (Tok.getLocation (), Tok.getEndLoc ());
124
- }
125
131
return halfOpenToRange (M, PatchedRange (R));
126
132
}
127
133
@@ -697,7 +703,10 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
697
703
SourceLocation PatchLoc =
698
704
translatePreamblePatchLocation (Info.getLocation (), SM);
699
705
D.InsideMainFile = isInsideMainFile (PatchLoc, SM);
700
- D.Range = diagnosticRange (Info, *LangOpts);
706
+ if (auto DRange = diagnosticRange (Info, *LangOpts))
707
+ D.Range = *DRange;
708
+ else
709
+ D.Severity = DiagnosticsEngine::Ignored;
701
710
auto FID = SM.getFileID (Info.getLocation ());
702
711
if (const auto FE = SM.getFileEntryRefForID (FID)) {
703
712
D.File = FE->getName ().str ();
0 commit comments