xref: /llvm-project/clang/test/Analysis/smart-ptr-text-output.cpp (revision d825309352b4c5c01da7c935e4aaaa9994f8f257)
106d100a6SNithin Vadukkumchery Rajendrakumar // RUN: %clang_analyze_cc1\
2*d8253093SDeep Majumder // RUN:  -analyzer-checker=core,cplusplus.Move,alpha.cplusplus.SmartPtr,debug.ExprInspection\
3*d8253093SDeep Majumder // RUN:  -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\
4*d8253093SDeep Majumder // RUN:  -analyzer-output=text -std=c++20 %s -verify=expected
5*d8253093SDeep Majumder 
6*d8253093SDeep Majumder // RUN: %clang_analyze_cc1\
7*d8253093SDeep Majumder // RUN:  -analyzer-checker=core,cplusplus.Move,alpha.cplusplus.SmartPtr,debug.ExprInspection\
806d100a6SNithin Vadukkumchery Rajendrakumar // RUN:  -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\
906d100a6SNithin Vadukkumchery Rajendrakumar // RUN:  -analyzer-output=text -std=c++11 %s -verify=expected
1006d100a6SNithin Vadukkumchery Rajendrakumar 
1106d100a6SNithin Vadukkumchery Rajendrakumar #include "Inputs/system-header-simulator-cxx.h"
1206d100a6SNithin Vadukkumchery Rajendrakumar 
13*d8253093SDeep Majumder void clang_analyzer_eval(bool);
14*d8253093SDeep Majumder 
1506d100a6SNithin Vadukkumchery Rajendrakumar class A {
1606d100a6SNithin Vadukkumchery Rajendrakumar public:
A()1706d100a6SNithin Vadukkumchery Rajendrakumar   A(){};
1806d100a6SNithin Vadukkumchery Rajendrakumar   void foo();
1906d100a6SNithin Vadukkumchery Rajendrakumar };
2006d100a6SNithin Vadukkumchery Rajendrakumar 
return_null()2106d100a6SNithin Vadukkumchery Rajendrakumar A *return_null() {
2206d100a6SNithin Vadukkumchery Rajendrakumar   return nullptr;
2306d100a6SNithin Vadukkumchery Rajendrakumar }
2406d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterDefaultCtr()2506d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterDefaultCtr() {
2606d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
2706d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
2806d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
2906d100a6SNithin Vadukkumchery Rajendrakumar }
3006d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterCtrWithNull()3106d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterCtrWithNull() {
3206d100a6SNithin Vadukkumchery Rajendrakumar   A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}
3306d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}}
3406d100a6SNithin Vadukkumchery Rajendrakumar   *P; // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
3506d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
3606d100a6SNithin Vadukkumchery Rajendrakumar }
3706d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterCtrWithNullVariable()3806d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterCtrWithNullVariable() {
3906d100a6SNithin Vadukkumchery Rajendrakumar   A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}
4006d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}}
4106d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
4206d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
4306d100a6SNithin Vadukkumchery Rajendrakumar }
4406d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterRelease()4506d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterRelease() {
46b34b1e38SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
47b34b1e38SNithin Vadukkumchery Rajendrakumar   // FIXME: should mark region as uninteresting after release, so above note will not be there
4806d100a6SNithin Vadukkumchery Rajendrakumar   P.release(); // expected-note {{Smart pointer 'P' is released and set to null}}
4906d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
5006d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
5106d100a6SNithin Vadukkumchery Rajendrakumar }
5206d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterReset()5306d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterReset() {
54b34b1e38SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
5506d100a6SNithin Vadukkumchery Rajendrakumar   P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}
5606d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
5706d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
5806d100a6SNithin Vadukkumchery Rajendrakumar }
5906d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterResetWithNull()6006d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterResetWithNull() {
6106d100a6SNithin Vadukkumchery Rajendrakumar   A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}}
62b34b1e38SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
6306d100a6SNithin Vadukkumchery Rajendrakumar   P.reset(NullInnerPtr); // expected-note {{Smart pointer 'P' reset using a null value}}
6406d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
6506d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
6606d100a6SNithin Vadukkumchery Rajendrakumar }
6706d100a6SNithin Vadukkumchery Rajendrakumar 
6806d100a6SNithin Vadukkumchery Rajendrakumar // FIXME: Fix this test when support is added for tracking raw pointer
6906d100a6SNithin Vadukkumchery Rajendrakumar // and mark the smart pointer as interesting based on that and add tags.
derefOnReleasedNullRawPtr()7006d100a6SNithin Vadukkumchery Rajendrakumar void derefOnReleasedNullRawPtr() {
7106d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null"
7206d100a6SNithin Vadukkumchery Rajendrakumar   A *AP = P.release(); // expected-note {{'AP' initialized to a null pointer value}}
7306d100a6SNithin Vadukkumchery Rajendrakumar   AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}}
7406d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Called C++ object pointer is null}}
7506d100a6SNithin Vadukkumchery Rajendrakumar }
7606d100a6SNithin Vadukkumchery Rajendrakumar 
derefOnSwappedNullPtr()7706d100a6SNithin Vadukkumchery Rajendrakumar void derefOnSwappedNullPtr() {
78b34b1e38SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
790cd98befSDeep Majumder   std::unique_ptr<A> PNull;
800cd98befSDeep Majumder   P.swap(PNull);
8106d100a6SNithin Vadukkumchery Rajendrakumar   PNull->foo(); // No warning.
8206d100a6SNithin Vadukkumchery Rajendrakumar   (*P).foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
8306d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
8406d100a6SNithin Vadukkumchery Rajendrakumar }
8506d100a6SNithin Vadukkumchery Rajendrakumar 
derefOnStdSwappedNullPtr()8606d100a6SNithin Vadukkumchery Rajendrakumar void derefOnStdSwappedNullPtr() {
87b34b1e38SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
880cd98befSDeep Majumder   std::unique_ptr<A> PNull;
890cd98befSDeep Majumder   std::swap(P, PNull);
9006d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
9106d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
9206d100a6SNithin Vadukkumchery Rajendrakumar }
9306d100a6SNithin Vadukkumchery Rajendrakumar 
9406d100a6SNithin Vadukkumchery Rajendrakumar struct StructWithSmartPtr { // expected-note {{Default constructed smart pointer 'S.P' is null}}
9506d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P;
9606d100a6SNithin Vadukkumchery Rajendrakumar };
9706d100a6SNithin Vadukkumchery Rajendrakumar 
derefAfterDefaultCtrInsideStruct()9806d100a6SNithin Vadukkumchery Rajendrakumar void derefAfterDefaultCtrInsideStruct() {
9906d100a6SNithin Vadukkumchery Rajendrakumar   StructWithSmartPtr S; // expected-note {{Calling implicit default constructor for 'StructWithSmartPtr'}}
10006d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Returning from default constructor for 'StructWithSmartPtr'}}
10106d100a6SNithin Vadukkumchery Rajendrakumar   S.P->foo(); // expected-warning {{Dereference of null smart pointer 'S.P' [alpha.cplusplus.SmartPtr]}}
10206d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'S.P'}}
10306d100a6SNithin Vadukkumchery Rajendrakumar }
10406d100a6SNithin Vadukkumchery Rajendrakumar 
noNoteTagsForNonInterestingRegion()10506d100a6SNithin Vadukkumchery Rajendrakumar void noNoteTagsForNonInterestingRegion() {
10606d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
10706d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P1; // No note.
10806d100a6SNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P2; // No note.
10906d100a6SNithin Vadukkumchery Rajendrakumar   P1.release(); // No note.
11006d100a6SNithin Vadukkumchery Rajendrakumar   P1.reset(); // No note.
11106d100a6SNithin Vadukkumchery Rajendrakumar   P1.swap(P2); // No note.
11206d100a6SNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
11306d100a6SNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
11406d100a6SNithin Vadukkumchery Rajendrakumar }
11506d100a6SNithin Vadukkumchery Rajendrakumar 
derefOnRawPtrFromGetOnNullPtr()11655208f5aSNithin Vadukkumchery Rajendrakumar void derefOnRawPtrFromGetOnNullPtr() {
11755208f5aSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null"
11855208f5aSNithin Vadukkumchery Rajendrakumar   P.get()->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}}
11955208f5aSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Called C++ object pointer is null}}
12055208f5aSNithin Vadukkumchery Rajendrakumar }
12155208f5aSNithin Vadukkumchery Rajendrakumar 
derefOnRawPtrFromGetOnValidPtr()12255208f5aSNithin Vadukkumchery Rajendrakumar void derefOnRawPtrFromGetOnValidPtr() {
12355208f5aSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A());
12455208f5aSNithin Vadukkumchery Rajendrakumar   P.get()->foo(); // No warning.
12555208f5aSNithin Vadukkumchery Rajendrakumar }
12655208f5aSNithin Vadukkumchery Rajendrakumar 
derefOnRawPtrFromGetOnUnknownPtr(std::unique_ptr<A> P)12755208f5aSNithin Vadukkumchery Rajendrakumar void derefOnRawPtrFromGetOnUnknownPtr(std::unique_ptr<A> P) {
12855208f5aSNithin Vadukkumchery Rajendrakumar   P.get()->foo(); // No warning.
12955208f5aSNithin Vadukkumchery Rajendrakumar }
13020676cabSNithin Vadukkumchery Rajendrakumar 
derefOnMovedFromValidPtr()13120676cabSNithin Vadukkumchery Rajendrakumar void derefOnMovedFromValidPtr() {
13220676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove(new A());  // expected-note {{Smart pointer 'PToMove' is constructed}}
13320676cabSNithin Vadukkumchery Rajendrakumar   // FIXME: above note should go away once we fix marking region not interested.
13420676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P;
13520676cabSNithin Vadukkumchery Rajendrakumar   P = std::move(PToMove); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}
13620676cabSNithin Vadukkumchery Rajendrakumar   PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}
13720676cabSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Dereference of null smart pointer 'PToMove'}}
13820676cabSNithin Vadukkumchery Rajendrakumar }
13920676cabSNithin Vadukkumchery Rajendrakumar 
derefOnMovedToNullPtr()14020676cabSNithin Vadukkumchery Rajendrakumar void derefOnMovedToNullPtr() {
14120676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove(new A());
14220676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P;
14320676cabSNithin Vadukkumchery Rajendrakumar   P = std::move(PToMove); // No note.
14420676cabSNithin Vadukkumchery Rajendrakumar   P->foo(); // No warning.
14520676cabSNithin Vadukkumchery Rajendrakumar }
14620676cabSNithin Vadukkumchery Rajendrakumar 
derefOnNullPtrGotMovedFromValidPtr()14720676cabSNithin Vadukkumchery Rajendrakumar void derefOnNullPtrGotMovedFromValidPtr() {
14820676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
14920676cabSNithin Vadukkumchery Rajendrakumar   // FIXME: above note should go away once we fix marking region not interested.
15020676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}
1511b743a9eSNithin Vadukkumchery Rajendrakumar   P = std::move(PToMove); // expected-note {{A null pointer value is moved to 'P'}}
15220676cabSNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
15320676cabSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Dereference of null smart pointer 'P'}}
15420676cabSNithin Vadukkumchery Rajendrakumar }
15520676cabSNithin Vadukkumchery Rajendrakumar 
derefOnMovedUnknownPtr(std::unique_ptr<A> PToMove)15620676cabSNithin Vadukkumchery Rajendrakumar void derefOnMovedUnknownPtr(std::unique_ptr<A> PToMove) {
15720676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P;
15820676cabSNithin Vadukkumchery Rajendrakumar   P = std::move(PToMove); // expected-note {{Smart pointer 'PToMove' is null after; previous value moved to 'P'}}
15920676cabSNithin Vadukkumchery Rajendrakumar   PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}
16020676cabSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Dereference of null smart pointer 'PToMove'}}
16120676cabSNithin Vadukkumchery Rajendrakumar }
16220676cabSNithin Vadukkumchery Rajendrakumar 
derefOnAssignedNullPtrToNullSmartPtr()16320676cabSNithin Vadukkumchery Rajendrakumar void derefOnAssignedNullPtrToNullSmartPtr() {
16420676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
16520676cabSNithin Vadukkumchery Rajendrakumar   P = nullptr; // expected-note {{Smart pointer 'P' is assigned to null}}
16620676cabSNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
16720676cabSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Dereference of null smart pointer 'P'}}
16820676cabSNithin Vadukkumchery Rajendrakumar }
16920676cabSNithin Vadukkumchery Rajendrakumar 
derefOnAssignedZeroToNullSmartPtr()17020676cabSNithin Vadukkumchery Rajendrakumar void derefOnAssignedZeroToNullSmartPtr() {
17120676cabSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}}
17220676cabSNithin Vadukkumchery Rajendrakumar   // FIXME: above note should go away once we fix marking region not interested.
17320676cabSNithin Vadukkumchery Rajendrakumar   P = 0; // expected-note {{Smart pointer 'P' is assigned to null}}
17420676cabSNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
17520676cabSNithin Vadukkumchery Rajendrakumar   // expected-note@-1 {{Dereference of null smart pointer 'P'}}
17620676cabSNithin Vadukkumchery Rajendrakumar }
1771b743a9eSNithin Vadukkumchery Rajendrakumar 
derefMoveConstructedWithNullPtr()1781b743a9eSNithin Vadukkumchery Rajendrakumar void derefMoveConstructedWithNullPtr() {
1791b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}
1801b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{A null pointer value is moved to 'P'}}
1811b743a9eSNithin Vadukkumchery Rajendrakumar   P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
1821b743a9eSNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'P'}}
1831b743a9eSNithin Vadukkumchery Rajendrakumar }
1841b743a9eSNithin Vadukkumchery Rajendrakumar 
derefValidPtrMovedToConstruct()1851b743a9eSNithin Vadukkumchery Rajendrakumar void derefValidPtrMovedToConstruct() {
1861b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove(new A()); // expected-note {{Smart pointer 'PToMove' is constructed}}
1871b743a9eSNithin Vadukkumchery Rajendrakumar   // FIXME: above note should go away once we fix marking region not interested.
1881b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}
1891b743a9eSNithin Vadukkumchery Rajendrakumar   PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}
1901b743a9eSNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}
1911b743a9eSNithin Vadukkumchery Rajendrakumar }
1921b743a9eSNithin Vadukkumchery Rajendrakumar 
derefNullPtrMovedToConstruct()1931b743a9eSNithin Vadukkumchery Rajendrakumar void derefNullPtrMovedToConstruct() {
1941b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PToMove; // expected-note {{Default constructed smart pointer 'PToMove' is null}}
1951b743a9eSNithin Vadukkumchery Rajendrakumar   // FIXME: above note should go away once we fix marking region not interested.
1961b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after being moved to 'P'}}
1971b743a9eSNithin Vadukkumchery Rajendrakumar   PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}
1981b743a9eSNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}
1991b743a9eSNithin Vadukkumchery Rajendrakumar }
2001b743a9eSNithin Vadukkumchery Rajendrakumar 
derefUnknownPtrMovedToConstruct(std::unique_ptr<A> PToMove)2011b743a9eSNithin Vadukkumchery Rajendrakumar void derefUnknownPtrMovedToConstruct(std::unique_ptr<A> PToMove) {
2021b743a9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(std::move(PToMove)); // expected-note {{Smart pointer 'PToMove' is null after; previous value moved to 'P'}}
2031b743a9eSNithin Vadukkumchery Rajendrakumar   PToMove->foo(); // expected-warning {{Dereference of null smart pointer 'PToMove' [alpha.cplusplus.SmartPtr]}}
2041b743a9eSNithin Vadukkumchery Rajendrakumar   // expected-note@-1{{Dereference of null smart pointer 'PToMove'}}
2051b743a9eSNithin Vadukkumchery Rajendrakumar }
206bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnNullPtrFalseBranch()207bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnNullPtrFalseBranch() {
208bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
209bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (P) { // expected-note {{Taking false branch}}
210bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P->foo(); // No warning.
211bc3d4d9eSNithin Vadukkumchery Rajendrakumar   } else {
212bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
213bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'P'}}
214bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
215bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
216bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnNullPtrTrueBranch()217bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnNullPtrTrueBranch() {
218bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}}
219bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (!P) { // expected-note {{Taking true branch}}
220bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
221bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'P'}}
222bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
223bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
224bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnValidPtrTrueBranch()225bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnValidPtrTrueBranch() {
226bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A());
227bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}
228bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (P) { // expected-note {{Taking true branch}}
229bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}
230bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'PNull'}}
231bc3d4d9eSNithin Vadukkumchery Rajendrakumar   } else {
232bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // No warning
233bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
234bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
235bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnValidPtrFalseBranch()236bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnValidPtrFalseBranch() {
237bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A());
238bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}
239bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (!P) { // expected-note {{Taking false branch}}
240bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // No warning
241bc3d4d9eSNithin Vadukkumchery Rajendrakumar   } else {
242bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}
243bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'PNull'}}
244bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
245bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
246bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnNotValidPtr()247bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnNotValidPtr() {
248bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> P(new A());
249bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PNull;
250bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (!P)
251bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // No warning.
252bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
253bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnUnKnownPtrAssumeNull(std::unique_ptr<A> P)254bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnUnKnownPtrAssumeNull(std::unique_ptr<A> P) {
255bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}
256bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (!P) { // expected-note {{Taking true branch}}
257bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Assuming smart pointer 'P' is null}}
258bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}
259bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'PNull'}}
260bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
261bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
262bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefConditionOnUnKnownPtrAssumeNonNull(std::unique_ptr<A> P)263bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefConditionOnUnKnownPtrAssumeNonNull(std::unique_ptr<A> P) {
264bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}}
265bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (P) { // expected-note {{Taking true branch}}
266bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Assuming smart pointer 'P' is non-null}}
267bc3d4d9eSNithin Vadukkumchery Rajendrakumar     PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}}
268bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'PNull'}}
269bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
270bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
271bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
derefOnValidPtrAfterReset(std::unique_ptr<A> P)272bc3d4d9eSNithin Vadukkumchery Rajendrakumar void derefOnValidPtrAfterReset(std::unique_ptr<A> P) {
273bc3d4d9eSNithin Vadukkumchery Rajendrakumar   P.reset(new A());
274bc3d4d9eSNithin Vadukkumchery Rajendrakumar   if (!P)
275bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P->foo(); // No warning.
276bc3d4d9eSNithin Vadukkumchery Rajendrakumar   else
277bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P->foo(); // No warning.
278bc3d4d9eSNithin Vadukkumchery Rajendrakumar }
279bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
280bc3d4d9eSNithin Vadukkumchery Rajendrakumar struct S {
281bc3d4d9eSNithin Vadukkumchery Rajendrakumar   std::unique_ptr<int> P;
282bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
fooS283bc3d4d9eSNithin Vadukkumchery Rajendrakumar   void foo() {
284bc3d4d9eSNithin Vadukkumchery Rajendrakumar     if (!P) { // No-note because foo() is pruned
285bc3d4d9eSNithin Vadukkumchery Rajendrakumar       return;
286bc3d4d9eSNithin Vadukkumchery Rajendrakumar     }
287bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
288bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
callingFooWithNullPointerS289bc3d4d9eSNithin Vadukkumchery Rajendrakumar   int callingFooWithNullPointer() {
290bc3d4d9eSNithin Vadukkumchery Rajendrakumar     foo(); // No note on Calling 'S::foo'
291bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P.reset(new int(0)); // expected-note {{Assigning 0}}
292bc3d4d9eSNithin Vadukkumchery Rajendrakumar     return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}
293bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1 {{Division by zero}}
294bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
295bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
callingFooWithValidPointerS296bc3d4d9eSNithin Vadukkumchery Rajendrakumar   int callingFooWithValidPointer() {
297bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P.reset(new int(0)); // expected-note {{Assigning 0}}
298bc3d4d9eSNithin Vadukkumchery Rajendrakumar     foo(); // No note on Calling 'S::foo'
299bc3d4d9eSNithin Vadukkumchery Rajendrakumar     return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}
300bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1 {{Division by zero}}
301bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
302bc3d4d9eSNithin Vadukkumchery Rajendrakumar 
callingFooWithUnknownPointerS303bc3d4d9eSNithin Vadukkumchery Rajendrakumar   int callingFooWithUnknownPointer(std::unique_ptr<int> PUnknown) {
304bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P.swap(PUnknown);
305bc3d4d9eSNithin Vadukkumchery Rajendrakumar     foo(); // No note on Calling 'S::foo'
306bc3d4d9eSNithin Vadukkumchery Rajendrakumar     P.reset(new int(0)); // expected-note {{Assigning 0}}
307bc3d4d9eSNithin Vadukkumchery Rajendrakumar     return 1 / *(P.get()); // expected-warning {{Division by zero [core.DivideZero]}}
308bc3d4d9eSNithin Vadukkumchery Rajendrakumar     // expected-note@-1 {{Division by zero}}
309bc3d4d9eSNithin Vadukkumchery Rajendrakumar   }
310bc3d4d9eSNithin Vadukkumchery Rajendrakumar };
3110b4fe808SNithin Vadukkumchery Rajendrakumar 
derefAfterBranchingOnUnknownInnerPtr(std::unique_ptr<A> P)3120b4fe808SNithin Vadukkumchery Rajendrakumar void derefAfterBranchingOnUnknownInnerPtr(std::unique_ptr<A> P) {
3130b4fe808SNithin Vadukkumchery Rajendrakumar   A *RP = P.get();
3140b4fe808SNithin Vadukkumchery Rajendrakumar   if (!RP) { // expected-note {{Assuming 'RP' is null}}
3150b4fe808SNithin Vadukkumchery Rajendrakumar     // expected-note@-1 {{Taking true branch}}
3160b4fe808SNithin Vadukkumchery Rajendrakumar     P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
3170b4fe808SNithin Vadukkumchery Rajendrakumar     // expected-note@-1{{Dereference of null smart pointer 'P'}}
3180b4fe808SNithin Vadukkumchery Rajendrakumar   }
3190b4fe808SNithin Vadukkumchery Rajendrakumar }
320*d8253093SDeep Majumder 
makeUniqueReturnsNonNullUniquePtr()321*d8253093SDeep Majumder void makeUniqueReturnsNonNullUniquePtr() {
322*d8253093SDeep Majumder   auto P = std::make_unique<A>();
323*d8253093SDeep Majumder   if (!P) {   // expected-note {{Taking false branch}}
324*d8253093SDeep Majumder     P->foo(); // should have no warning here, path is impossible
325*d8253093SDeep Majumder   }
326*d8253093SDeep Majumder   P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}
327*d8253093SDeep Majumder   // Now P is null
328*d8253093SDeep Majumder   if (!P) {
329*d8253093SDeep Majumder     // expected-note@-1 {{Taking true branch}}
330*d8253093SDeep Majumder     P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
331*d8253093SDeep Majumder     // expected-note@-1{{Dereference of null smart pointer 'P'}}
332*d8253093SDeep Majumder   }
333*d8253093SDeep Majumder }
334*d8253093SDeep Majumder 
335*d8253093SDeep Majumder #if __cplusplus >= 202002L
336*d8253093SDeep Majumder 
makeUniqueForOverwriteReturnsNullUniquePtr()337*d8253093SDeep Majumder void makeUniqueForOverwriteReturnsNullUniquePtr() {
338*d8253093SDeep Majumder   auto P = std::make_unique_for_overwrite<A>();
339*d8253093SDeep Majumder   if (!P) {   // expected-note {{Taking false branch}}
340*d8253093SDeep Majumder     P->foo(); // should have no warning here, path is impossible
341*d8253093SDeep Majumder   }
342*d8253093SDeep Majumder   P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}}
343*d8253093SDeep Majumder   // Now P is null
344*d8253093SDeep Majumder   if (!P) {
345*d8253093SDeep Majumder     // expected-note@-1 {{Taking true branch}}
346*d8253093SDeep Majumder     P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}}
347*d8253093SDeep Majumder     // expected-note@-1{{Dereference of null smart pointer 'P'}}
348*d8253093SDeep Majumder   }
349*d8253093SDeep Majumder }
350*d8253093SDeep Majumder 
351*d8253093SDeep Majumder #endif
352*d8253093SDeep Majumder 
353*d8253093SDeep Majumder struct G {
354*d8253093SDeep Majumder   int *p;
GG355*d8253093SDeep Majumder   G(int *p): p(p) {}
~GG356*d8253093SDeep Majumder   ~G() { *p = 0; }
357*d8253093SDeep Majumder };
358*d8253093SDeep Majumder 
foo()359*d8253093SDeep Majumder void foo() {
360*d8253093SDeep Majumder   int x = 1;
361*d8253093SDeep Majumder   {
362*d8253093SDeep Majumder     auto P = std::make_unique<G>(&x);
363*d8253093SDeep Majumder     // FIXME: There should not be a state split here, it should take the true path.
364*d8253093SDeep Majumder     clang_analyzer_eval(*P->p == 1); // expected-warning {{TRUE}}
365*d8253093SDeep Majumder     // expected-warning@-1 {{FALSE}}
366*d8253093SDeep Majumder     // expected-note@-2 {{Assuming the condition is true}}
367*d8253093SDeep Majumder     // expected-note@-3 {{Assuming the condition is false}}
368*d8253093SDeep Majumder     // expected-note@-4 {{TRUE}}
369*d8253093SDeep Majumder     // expected-note@-5 {{FALSE}}
370*d8253093SDeep Majumder     // expected-note@-6 {{Assuming the condition is false}}
371*d8253093SDeep Majumder   }
372*d8253093SDeep Majumder   // FIXME: Should be fixed when unique_ptr desctructors are
373*d8253093SDeep Majumder   // properly modelled. This includes modelling the call to
374*d8253093SDeep Majumder   // the destructor of the inner pointer type.
375*d8253093SDeep Majumder   clang_analyzer_eval(x == 0); // expected-warning {{FALSE}}
376*d8253093SDeep Majumder   // expected-note@-1 {{FALSE}}
377*d8253093SDeep Majumder }
378