[PATCH] D84600: [Analyzer] Support note tags for smart ptr checker

Artem Dergachev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 26 17:58:17 PDT 2020


NoQ added inline comments.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp:179
+
+  switch (SmartPtrMethod) {
+  case Constructor: {
----------------
NoQ wrote:
> I feel this is a bit over-engineered. There's no need to create an enum and later convert it into a string when you can capture a string directly. Like, this entire "details" structure of your, it should be just captures instead, and your strings would make it immediately obvious what kind of note is emitted:
> ```lang=c++
> C.addTransition(State, getNoteTag([R](PathSensitiveBugReport &BR) {
>   if (&BR.getBugType() != &NullDereferenceBugType || !R->isInteresting())
>     return "";
>  
>   return Twine("Default constructed smart pointer '") + getSmartPtrName(R) + "' is null";
> }));
> ```
> 
> Hmm, maybe we should also provide an overload with lambdas of signature`void(PathSensitiveBugReport &BR, llvm::raw_ostream OS)` so that to make the same one-liners possible with streams? Something like this:
> 
> ```lang=c++
> class CheckerContext {
> // ...
>   NoteTag *getNoteTag(std::function<void(PathSensitiveBugReport &BR, llvm::raw_ostream OS)> f) {
>     return getNoteTag([](PathSensitiveBugReport &BR) -> std::string {
>       llvm::SmallString<128> Str;
>       llvm::raw_svector_ostream OS(Str);
>       f(BR, OS);
>       return OS.str();
>     });
>   }
> // ...
> };
> ```
> 
> Then you could do:
> ```lang=c++
> C.addTransition(State, getNoteTag([R](PathSensitiveBugReport &BR) {
>   if (&BR.getBugType() != &NullDereferenceBugType || !R->isInteresting())
>     return;
> 
>   OS << "Default constructed smart pointer '" << getSmartPtrName(R) << "' is null";
> }));
> ```
(forgot `, llvm::raw_ostream OS` in the last snippet; probably forgot a bunch of other stuff because i didn't try to actually compile these snippets)


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp:408-412
+        SmallString<128> Msg;
+        llvm::raw_svector_ostream Out(Msg);
+        TagDetails.trackValidExpr(BR);
+        TagDetails.explainSmartPtrAction(Out);
+        return std::string(Out.str());
----------------
NoQ wrote:
> Ok, note that note tags are attached to nodes independently of bug reports; when the report is thrown, only then we know what are the smart pointers that should be explained.
> 
> So there are two checks that you should do here:
> 
> 1. Check that the bug report is emitted by your checker (eg., by comparing bug types). If not, don't add notes.
> 
> 2. Check that the region about which the note speaks is related to your report (i.e., it's not a completely unrelated smart pointer). You can do that by marking the smart pointer as "interesting" (i.e., `PathSensitiveBugReport::markIntersting()`) when you emit the report, and then in the lambda you check whether the smart pointer is interesting before you emit a note. Additionally, you can carry over interestingness when smart pointers are copied.
> 
> This is what i was trying to accomplish with this code snippet that i included in the examples in the other comment:
> ```lang=c++
>   if (&BR.getBugType() != &NullDereferenceBugType || !R->isInteresting())
>     return "";
> ```
(i strongly recommend having test cases for both of these issues)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84600





More information about the cfe-commits mailing list