This partially fixes https://bugs.llvm.org/show_bug.cgi?id=41218.
Details
- Reviewers
ilya-biryukov sammccall - Commits
- rZORG6e5203b87ffe: [clangd] Respect clang-tidy suppression comments
rG6e5203b87ffe: [clangd] Respect clang-tidy suppression comments
rGc2aded501776: [clangd] Respect clang-tidy suppression comments
rCTE361112: [clangd] Respect clang-tidy suppression comments
rL361112: [clangd] Respect clang-tidy suppression comments
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 32033 Build 32032: arc lint + arc unit
Event Timeline
Thanks for doing this!
clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp | ||
---|---|---|
401 | There may be a trap here for clangd. When building an AST with a preamble (which is when we run clang-tidy checks), the source code of the main file is mapped in the SourceManager as usual, but headers are not. @ilya-biryukov knows the details here better than me. Of course this is only true for trying to read from header file locations, and we only run clang-tidy over main-file-decls. But:
Maybe this means we can't accurately calculate suppression for clang-tidy warnings in macro locations, or outside the main file. I think *always* filtering these out (on the clangd side) might be OK. | |
clang-tools-extra/clangd/ClangdUnit.cpp | ||
292 | the interaction between ClangdDiagnosticConsumer and StoreDiags seems a little mysterious - I think the total behavior would be easier to understand (and debug) if StoreDiags knew about the filtering. At the same time, I see why you want to keep the clang-tidy-specific logic in this file. Maybe we could add a filterDiagnostics(function<bool(Diagnostic&)>) or so into StoreDiags, similar to contributeFixes? That way the policy stuff (which diagnostics to filter) stays here, and the mechanism (e.g. tracking associated notes) is visible in StoreDiags. |
clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp | ||
---|---|---|
401 | Thanks for pointing this out! This should be addressed in the updated patch. |
Thanks, this looks nice. Main ideas here:
- it'd be nice to get rid of the subclassing in the diag consumer if we can
- i'm not sure the logic around LastErrorWasIgnored is completely accurate
- can we add a unit test for this? The existing clang-tidy diag tests are in unittests/DiagnosticsTests.cpp
clang-tools-extra/clangd/ClangdUnit.cpp | ||
---|---|---|
281 | Thanks, this is much cleaner. I think we don't need the subclass at all though - just a filter function here, and call setFilter after setting up clang-tidy? | |
365 | I believe you can just call setFilter at the end of this block | |
clang-tools-extra/clangd/Diagnostics.cpp | ||
444 | do we need to set LastErrorWasIgnored here (in the case that it's not a note)? I guess it's pretty unlikely that e.g. a problem with the command-line will get a note that has a source location... | |
449 | Can you add a comment here, about notes attached to suppressed errors? This code is under-commented (sorry), but I think it would aid understanding. | |
451 | If I read the code right, we're now applying the filter to a note (whose primary diagnostic was ignored), which we shouldn't. We're also updating the LastErrorWasIgnored flag, which we shouldn't for notes. I think we might prefer to merge the new logic with the bit below the lambdas, which already looks at note/non-note status. e.g. if (!isNote(...)) { flushLastDiag(); LastErrorWasIgnored = !Filter(...); if (LastErrorWasIgnored) return; ... } else { // Handle a note... if (LastErrorWasIgnored) return; ... } | |
clang-tools-extra/clangd/Diagnostics.h | ||
133 | nit: IsInsideMainFile is information already inside the diagnostic. Diagnostics.cpp does compute this information (in an unneccesarily verbose way IMO) but I'd prefer not to expose that in this public interface - the filter function can recompute. | |
136 | I know I suggested this name, but just an idea... The difficulty with filter is it's unclear whether true means "this passes the filter" or "this is filtered out". It may be clearer to invert the sense and call this suppress. Anyway, totally up to you, can definitely live with filter. | |
148 | I think we're talking about last non-note diagnostic, right? Warnings count here I think. At the risk of being verbose, maybe LastPrimaryDiagnosticWasIgnored? |
Address review comments, except for the derived class one, about which I have a question
clang-tools-extra/clangd/ClangdUnit.cpp | ||
---|---|---|
281 | I rely on the derived class more in the follow-up patch D61841 where I override HandleDiagnostic(). Should I still remove it from this patch? | |
clang-tools-extra/clangd/Diagnostics.cpp | ||
444 | If that does happen, then it looks like storing the note in that case is a pre-existing behaviour, which this patch just preserves. | |
clang-tools-extra/clangd/Diagnostics.h | ||
148 | I copied the name from ClangTidyDiagnosticConsumer::LastErrorWasIgnored, but sure, I can rename this as suggested. |
Thanks, this looks good. I think we should avoid the subclassing, but any of {generalize in the next patch, different approach for the next patch, subclass for now and clean up later} seems fine.
clang-tools-extra/clangd/ClangdUnit.cpp | ||
---|---|---|
281 | Sorry about not understanding the interaction here, I wasn't aware of the warnings-to-errors work. A couple of options spring to mind here:
(sorry about the churn here, I wasn't aware of the followup patch) | |
clang-tools-extra/clangd/Diagnostics.h | ||
115 | nit: this really doesn't seem worth adding to a public interface, is D.hasSourceManager() && D.getSourceManager().isWrittenInMainFile(D.getLocation()) really too verbose? (I don't think the helper function in Diagnostics.cpp is justified either, but unrelated to this patch) | |
clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp | ||
791 | nit: can we group this with the other ClangTidy test? |
There may be a trap here for clangd.
When building an AST with a preamble (which is when we run clang-tidy checks), the source code of the main file is mapped in the SourceManager as usual, but headers are not.
An attempt to get the buffer results in the SourceManager reading the file from disk. If the content has changed then all sorts of invariants break and clang will typically crash.
@ilya-biryukov knows the details here better than me.
Of course this is only true for trying to read from header file locations, and we only run clang-tidy over main-file-decls. But:
Maybe this means we can't accurately calculate suppression for clang-tidy warnings in macro locations, or outside the main file. I think *always* filtering these out (on the clangd side) might be OK.