[PATCH] D81315: [analyzer] Warning for default constructed unique pointer dereferences

Nithin VR via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 3 11:17:24 PDT 2020


vrnithinkumar added inline comments.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp:41
+
+  bool checkDeferenceOps(const CallEvent &Call, CheckerContext &C) const;
+};
----------------
NoQ wrote:
> Looks like dead code.
Thanks!
removed.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp:72
+      NullDereferenceBugType, "Dereference of null smart pointer", ErrNode);
+  R->addRange(Call.getSourceRange());
+  C.emitReport(std::move(R));
----------------
NoQ wrote:
> This is probably unnecessary. The default `SourceRange` highlighted in path-sensitive report is the error node's statement and it should be exactly the same.
Removed.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp:67-80
+bool isStdSmartPtrCall(const CallEvent &Call) {
+  const auto *MethodDecl = dyn_cast_or_null<CXXMethodDecl>(Call.getDecl());
+  if (!MethodDecl || !MethodDecl->getParent())
+    return false;
+
+  const auto *RecordDecl = MethodDecl->getParent();
+  if (!RecordDecl || !RecordDecl->getDeclContext()->isStdNamespace())
----------------
NoQ wrote:
> Ok, so the normal solution to this problem is to make this logic a part of your `CallDescriptionMap`:
> 
> ```lang=c++
>   CallDescriptionMap<SmartPtrMethodHandlerFn> SmartPtrMethodHandlers{
> 
>     {{"std", "unique_ptr", "reset"}, &SmartPtrModeling::handleReset},
>     {{"std", "unique_ptr", "release"}, &SmartPtrModeling::handleRelease},
>     {{"std", "unique_ptr", "swap", 1}, &SmartPtrModeling::handleSwap},
> 
>     {{"std", "shared_ptr", "reset"}, &SmartPtrModeling::handleReset},
>     {{"std", "shared_ptr", "release"}, &SmartPtrModeling::handleRelease},
>     {{"std", "shared_ptr", "swap", 1}, &SmartPtrModeling::handleSwap},
> 
>     {{"std", "weak_ptr", "reset"}, &SmartPtrModeling::handleReset},
>     {{"std", "weak_ptr", "release"}, &SmartPtrModeling::handleRelease},
>     {{"std", "weak_ptr", "swap", 1}, &SmartPtrModeling::handleSwap},
>   };
> ```
> 
> It looks like you're not doing this because `CallDescriptionMap` doesn't support operator calls yet. In fact, it looks like it doesn't support them because i'm not doing my homework by reviewing D81059. I just tried to catch up on it.
> 
> The other potential reason not to use `CallDescriptionMap` would be that you'll have to duplicate the list of methods for every smart pointer class you want to support. I don't think it's necessarily bad though, because different classes may in fact require different handling.
> 
> The downside of your solution, though, is that you're manually implementing the name matching logic that has been already implemented for you in `CallDescriptionMap`. And the reason we made `CallDescriptionMap` was because we really really wanted to re-use this logic because it's surprisingly difficult to implement correctly. One potential problem i see with your implementation is that you don't account for inline namespaces such as [[ https://github.com/llvm/llvm-project/blob/master/clang/unittests/StaticAnalyzer/CallDescriptionTest.cpp#L127 | libcxx's `__1` ]]. `CallDescriptionMap` knows about these things but they're almost impossible to discover independently when you're matching names by hand.
> 
> Let's leave this code as-is for now but try to get rid of this function as soon as possible (i.e., when D81059 lands).
Thanks for the details.
If I recall correctly, I also found that  `CallDescriptionMap` was not supporting constructors also. 
I am not sure why.
Is it because constructor name is a special name?


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp:50
+  void handleSwap(const CallEvent &Call, CheckerContext &C) const;
+  bool checkDeferenceOps(const CallEvent &Call, CheckerContext &C) const;
+
----------------
NoQ wrote:
> Looks like dead code.
Thanks!
removed.


================
Comment at: clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp:81
                                 CheckerContext &C) const {
-  if (!isNullAfterMoveMethod(Call))
+  if (isNullAfterMoveMethod(Call)) {
+    ProgramStateRef State = C.getState();
----------------
NoQ wrote:
> vrnithinkumar wrote:
> > xazax.hun wrote:
> > > Don't we want this to be also protected by the `isStdSmartPointerClass` check?
> > added `isStdSmartPointerClass` check in the beginning.
> Uh-oh, i'm shocked this wasn't in place before. Maybe we should do some code review or something. What idiot wrote this code anyway? Wait, it was me.
:)


================
Comment at: clang/test/Analysis/smart-ptr.cpp:5
 // RUN:   -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core\
+// RUN:   -analyzer-checker alpha.cplusplus.SmartPtr\
----------------
NoQ wrote:
> This second run-line no longer tests the option. The checker is disabled, of course there won't be any diagnostics. I think we should remove the second run-line now and i don't have much better tests in mind that we won't eventually remove as we write more code.
Okay thanks
removed the second line.


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

https://reviews.llvm.org/D81315





More information about the cfe-commits mailing list