diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp --- a/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp @@ -103,7 +103,8 @@ bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion) { const auto *InnerPointVal = State->get(ThisRegion); - return InnerPointVal && InnerPointVal->isZeroConstant(); + return InnerPointVal && + !State->assume(InnerPointVal->castAs(), true); } } // namespace smartptr } // namespace ento diff --git a/clang/test/Analysis/smart-ptr-text-output.cpp b/clang/test/Analysis/smart-ptr-text-output.cpp --- a/clang/test/Analysis/smart-ptr-text-output.cpp +++ b/clang/test/Analysis/smart-ptr-text-output.cpp @@ -304,3 +304,12 @@ // expected-note@-1 {{Division by zero}} } }; + +void derefAfterBranchingOnUnknownInnerPtr(std::unique_ptr P) { + A *RP = P.get(); + if (!RP) { // expected-note {{Assuming 'RP' is null}} + // expected-note@-1 {{Taking true branch}} + P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} + // expected-note@-1{{Dereference of null smart pointer 'P'}} + } +} diff --git a/clang/test/Analysis/smart-ptr.cpp b/clang/test/Analysis/smart-ptr.cpp --- a/clang/test/Analysis/smart-ptr.cpp +++ b/clang/test/Analysis/smart-ptr.cpp @@ -333,7 +333,7 @@ void drefOnAssignedNullFromMethodPtrValidSmartPtr() { std::unique_ptr P(new A()); P = returnRValRefOfUniquePtr(); - P->foo(); // No warning. + P->foo(); // No warning. } void derefMoveConstructedWithValidPtr() { @@ -374,7 +374,7 @@ void derefMoveConstructedWithRValueRefReturn() { std::unique_ptr P(functionReturnsRValueRef()); - P->foo(); // No warning. + P->foo(); // No warning. } void derefConditionOnNullPtr() { @@ -450,3 +450,10 @@ else return *P; // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} } + +void derefAfterBranchingOnUnknownInnerPtr(std::unique_ptr P) { + A *RP = P.get(); + if (!RP) { + P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} + } +}