[PATCH] D94476: [analyzer] Implement conversion from Clang diagnostics to PathDiagnostics.

Balázs Benics via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 12 07:12:20 PST 2021


steakhal added a comment.

Seems pretty straightforward and clean.

The cleanup of the report's message should be reworked.
Besides, that looks good to me.

I think these cases should be tested as well:

- [Warning, Warning, Warning]
- [Warning, Note, Note]
- [Warning, Note, Note, Warning, Note]
- [Warning, Note, Remark, Warning, Remark]

PS: clang-format; sorry for the nit-spam :D



================
Comment at: clang/include/clang/Analysis/PathDiagnosticConverterDiagnosticConsumer.h:53-56
+  /// Inform the consumer that the last diagnostic has been sent. This is
+  /// necessary because the consumer does not know whether more notes are
+  /// going to be attached to the last warning.
+  void finalize() { flushPartialDiagnostic(); }
----------------
Overriding the `virtual void clang::DiagnosticConsumer::finish()` can't accomplish the same thing?


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:1
+//===--- PathDiagnosticConverterDiagnosticConsumer.cpp ----------*- C++ -*-===//
+//
----------------
I've seen this a few times, and I still don't know why we use it.
The file extension should be enough to recognize that this is a C++ file.
Can someone clarify this?


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:14
+
+#include <clang/Analysis/PathDiagnosticConverterDiagnosticConsumer.h>
+
----------------
I frequently see `#include "clang/..."`-ish includes but never `#include <clang/...>`.


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:23
+
+  for (PathDiagnosticConsumer *Consumer : PathConsumers) {
+    Consumer->HandlePathDiagnostic(std::move(PartialPDs[Consumer]));
----------------



================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:37
+  Info.FormatDiagnostic(Msg);
+  Msg[0] = toupper(Msg[0]);
+  std::string CleanMsg = Msg.str().substr(0, Msg.str().find('[') - 1).str();
----------------



================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:38
+  Msg[0] = toupper(Msg[0]);
+  std::string CleanMsg = Msg.str().substr(0, Msg.str().find('[') - 1).str();
+
----------------
vsavchenko wrote:
> I think this type of stuff should be covered by a comment or a descriptive function name.
Eh, I don't think it's gonna work this way.
We can not assume that the `[` won't appear in the payload of the message.
Eg.:
`NewDelete-checker-test.cpp:193`
```
// newdelete-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
```

The best you could do is to do a reverse search.
Do we emit the `[mypackage.mychecker]` suffix for all the reports? If not, then we have a problem.


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:45-52
+  // For now we assume that every diagnostic is either a warning (or something
+  // similar, like an error) or a note logically attached to a previous warning.
+  // Notes do not come in actually attached to their respective warnings
+  // but are fed to us independently. The good news is they always follow their
+  // respective warnings and come in in the right order so we can
+  // automatically re-attach them.
+  // FIXME: Handle other stuff, like remarks(?)
----------------
So, `Error` and `Fatal`is treated in the same way as `Warning`.
What about the `Ignored`?


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:54-60
+      PathDiagnosticPieceRef Piece;
+      if (ShouldDisplayNotesAsEvents) {
+        Piece = std::make_shared<PathDiagnosticEventPiece>(PDLoc, Msg);
+      } else {
+        Piece = std::make_shared<PathDiagnosticNotePiece>(PDLoc, Msg);
+      }
+      PartialPDs[Consumer]->getMutablePieces().push_back(Piece);
----------------
The ternary operator could simplify this inside the `push_back` function - `emplace_back`?


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:71
+          BTI.CheckName, /*DeclWithIssue=*/nullptr, BTI.BugType,
+          CleanMsg, CleanMsg, BTI.BugCategory, PDLoc, /*DeclToUnique=*/nullptr,
+          std::make_unique<FilesToLineNumsMap>());
----------------
Should Desc and ShortDesc be the same?


================
Comment at: clang/lib/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:74-77
+      PathDiagnosticPieceRef Piece =
+          std::make_shared<PathDiagnosticEventPiece>(PDLoc, CleanMsg);
+
+      PD->setEndOfPath(std::move(Piece));
----------------
Why not construct in place?


================
Comment at: clang/unittests/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:44
+
+  virtual StringRef getName() const override { return "test"; }
+
----------------
I would suggest removing the redundant `virtual`. The same applies to the other decls.


================
Comment at: clang/unittests/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:63
+      size_t PieceI = 0;
+      for (const auto &Piece: Pieces) {
+        const ExpectedPieceTy &ExpectedPiece = ExpectedDiag.Pieces[PieceI];
----------------
vsavchenko wrote:
> vsavchenko wrote:
> > nit
> nit: `llvm::enumerate` or `llvm::zip`?
`clang-format` should format these files as well, am I right?


================
Comment at: clang/unittests/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:83
+
+  void performTest(const Decl *D) {
+    TestPathDiagnosticConsumer::ExpectedDiagsTy ExpectedDiags{
----------------
vsavchenko wrote:
> TBH it is pretty hard to follow the test and from it's structure see what is the input and what is expected output.  Maybe it can be reorganized a bit?
I can confirm.
What about passing the `ExpectedDiags` as a parameter?
Probably some shorter type alias could come handy for `TestPathDiagnosticConsumer::ExpectedDiagTy` and `TestPathDiagnosticConsumer::ExpectedPieceTy`.


================
Comment at: clang/unittests/Analysis/PathDiagnosticConverterDiagnosticConsumer.cpp:139
+
+class PathDiagnosticConverterDiagnosticConsumerTestAction
+    : public ASTFrontendAction {
----------------
vsavchenko wrote:
> WE NEED MORE NOUNS!
What about calling this `DiagnosticMock`?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D94476/new/

https://reviews.llvm.org/D94476



More information about the cfe-commits mailing list