Do not use clang_Location_isInSystemHeader for diagnostics; causes crashes

This commit is contained in:
Jacob Dufault 2017-07-12 15:02:48 -07:00
parent aae126f899
commit 00e452272f
4 changed files with 20 additions and 19 deletions

View File

@ -294,7 +294,8 @@ void EnsureDocumentParsed(ClangCompleteManager* manager,
NonElidedVector<lsDiagnostic> ls_diagnostics;
unsigned num_diagnostics = clang_getNumDiagnostics((*tu)->cx_tu);
for (unsigned i = 0; i < num_diagnostics; ++i) {
optional<lsDiagnostic> diagnostic = BuildAndDisposeDiagnostic(clang_getDiagnostic((*tu)->cx_tu, i));
optional<lsDiagnostic> diagnostic = BuildAndDisposeDiagnostic(
clang_getDiagnostic((*tu)->cx_tu, i), session->file.filename);
if (diagnostic)
ls_diagnostics.push_back(*diagnostic);
}
@ -404,20 +405,18 @@ void CompletionQueryMain(ClangCompleteManager* completion_manager) {
request->on_complete(ls_result, false /*is_cached_result*/);
timer.ResetAndPrint("[complete] Running user-given completion func");
/*
unsigned num_diagnostics = clang_codeCompleteGetNumDiagnostics(cx_results);
NonElidedVector<lsDiagnostic> ls_diagnostics;
std::cerr << "!! There are " + std::to_string(num_diagnostics) + " diagnostics to build\n";
for (unsigned i = 0; i < num_diagnostics; ++i) {
std::cerr << "!! Building diagnostic " + std::to_string(i) + "\n";
CXDiagnostic cx_diag = clang_codeCompleteGetDiagnostic(cx_results, i);
optional<lsDiagnostic> diagnostic = BuildAndDisposeDiagnostic(cx_diag);
optional<lsDiagnostic> diagnostic = BuildAndDisposeDiagnostic(cx_diag, path);
if (diagnostic)
ls_diagnostics.push_back(*diagnostic);
}
completion_manager->on_diagnostic_(session->file.filename, ls_diagnostics);
timer.ResetAndPrint("[complete] Build diagnostics");
*/
}
// Make sure |ls_results| is destroyed before clearing |cx_results|.

View File

@ -21,22 +21,22 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) {
} // namespace
optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic) {
// Skip diagnostics in system headers.
CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic);
if (clang_equalLocations(diag_loc, clang_getNullLocation()) ||
clang_Location_isInSystemHeader(diag_loc)) {
optional<lsDiagnostic> BuildAndDisposeDiagnostic(
CXDiagnostic diagnostic, const std::string& path) {
// Get diagnostic location.
CXFile file;
unsigned int line, column;
clang_getSpellingLocation(
clang_getDiagnosticLocation(diagnostic), &file, &line, &column, nullptr);
// Only report diagnostics in the same file. Using
// clang_Location_isInSystemHeader causes crashes for some reason.
if (path != FileName(file)) {
clang_disposeDiagnostic(diagnostic);
return nullopt;
}
// Get db so we can attribute diagnostic to the right indexed file.
CXFile file;
unsigned int line, column;
clang_getSpellingLocation(diag_loc, &file, &line, &column, nullptr);
// Build diagnostic.
lsDiagnostic ls_diagnostic;
// TODO: consider using clang_getDiagnosticRange

View File

@ -9,7 +9,8 @@
using namespace std::experimental;
optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic);
optional<lsDiagnostic> BuildAndDisposeDiagnostic(
CXDiagnostic diagnostic, const std::string& path);
// Returns the absolute path to |file|.
std::string FileName(CXFile file);

View File

@ -373,7 +373,7 @@ void diagnostic(CXClientData client_data,
for (unsigned i = 0; i < clang_getNumDiagnosticsInSet(diagnostics); ++i) {
CXDiagnostic diagnostic = clang_getDiagnosticInSet(diagnostics, i);
// Skip diagnostics in system headers.
CXSourceLocation diag_loc = clang_getDiagnosticLocation(diagnostic);
if (clang_Location_isInSystemHeader(diag_loc))
@ -386,9 +386,10 @@ void diagnostic(CXClientData client_data,
IndexFile* db = ConsumeFile(param, file);
if (!db)
continue;
// Build diagnostic.
optional<lsDiagnostic> ls_diagnostic = BuildAndDisposeDiagnostic(diagnostic);
optional<lsDiagnostic> ls_diagnostic =
BuildAndDisposeDiagnostic(diagnostic, db->path);
if (ls_diagnostic)
db->diagnostics_.push_back(*ls_diagnostic);
}