1 // RUN: %clang_analyze_cc1\ 2 // RUN: -analyzer-checker=core,cplusplus.Move,alpha.cplusplus.SmartPtr\ 3 // RUN: -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\ 4 // RUN: -analyzer-output=text -std=c++11 %s -verify=expected 5 6 #include "Inputs/system-header-simulator-cxx.h" 7 8 class A { 9 public: 10 A(){}; 11 void foo(); 12 }; 13 14 A *return_null() { 15 return nullptr; 16 } 17 18 void derefAfterDefaultCtr() { 19 std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}} 20 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 21 // expected-note@-1{{Dereference of null smart pointer 'P'}} 22 } 23 24 void derefAfterCtrWithNull() { 25 A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}} 26 std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}} 27 *P; // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 28 // expected-note@-1{{Dereference of null smart pointer 'P'}} 29 } 30 31 void derefAfterCtrWithNullVariable() { 32 A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}} 33 std::unique_ptr<A> P(NullInnerPtr); // expected-note {{Smart pointer 'P' is constructed using a null value}} 34 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 35 // expected-note@-1{{Dereference of null smart pointer 'P'}} 36 } 37 38 void derefAfterRelease() { 39 std::unique_ptr<A> P(new A()); 40 P.release(); // expected-note {{Smart pointer 'P' is released and set to null}} 41 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 42 // expected-note@-1{{Dereference of null smart pointer 'P'}} 43 } 44 45 void derefAfterReset() { 46 std::unique_ptr<A> P(new A()); 47 P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}} 48 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 49 // expected-note@-1{{Dereference of null smart pointer 'P'}} 50 } 51 52 void derefAfterResetWithNull() { 53 A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}} 54 std::unique_ptr<A> P(new A()); 55 P.reset(NullInnerPtr); // expected-note {{Smart pointer 'P' reset using a null value}} 56 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 57 // expected-note@-1{{Dereference of null smart pointer 'P'}} 58 } 59 60 // FIXME: Fix this test when support is added for tracking raw pointer 61 // and mark the smart pointer as interesting based on that and add tags. 62 void derefOnReleasedNullRawPtr() { 63 std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null" 64 A *AP = P.release(); // expected-note {{'AP' initialized to a null pointer value}} 65 AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} 66 // expected-note@-1{{Called C++ object pointer is null}} 67 } 68 69 void derefOnSwappedNullPtr() { 70 std::unique_ptr<A> P(new A()); 71 std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}} 72 P.swap(PNull); // expected-note {{Swapped null smart pointer 'PNull' with smart pointer 'P'}} 73 PNull->foo(); // No warning. 74 (*P).foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 75 // expected-note@-1{{Dereference of null smart pointer 'P'}} 76 } 77 78 // FIXME: Fix this test when "std::swap" is modeled seperately. 79 void derefOnStdSwappedNullPtr() { 80 std::unique_ptr<A> P; 81 std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}} 82 std::swap(P, PNull); // expected-note@Inputs/system-header-simulator-cxx.h:978 {{Swapped null smart pointer 'PNull' with smart pointer 'P'}} 83 // expected-note@-1 {{Calling 'swap<A>'}} 84 // expected-note@-2 {{Returning from 'swap<A>'}} 85 PNull->foo(); // expected-warning {{Dereference of null smart pointer 'PNull' [alpha.cplusplus.SmartPtr]}} 86 // expected-note@-1{{Dereference of null smart pointer 'PNull'}} 87 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 88 // expected-note@-1{{Dereference of null smart pointer 'P'}} 89 } 90 91 struct StructWithSmartPtr { // expected-note {{Default constructed smart pointer 'S.P' is null}} 92 std::unique_ptr<A> P; 93 }; 94 95 void derefAfterDefaultCtrInsideStruct() { 96 StructWithSmartPtr S; // expected-note {{Calling implicit default constructor for 'StructWithSmartPtr'}} 97 // expected-note@-1 {{Returning from default constructor for 'StructWithSmartPtr'}} 98 S.P->foo(); // expected-warning {{Dereference of null smart pointer 'S.P' [alpha.cplusplus.SmartPtr]}} 99 // expected-note@-1{{Dereference of null smart pointer 'S.P'}} 100 } 101 102 void noNoteTagsForNonInterestingRegion() { 103 std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}} 104 std::unique_ptr<A> P1; // No note. 105 std::unique_ptr<A> P2; // No note. 106 P1.release(); // No note. 107 P1.reset(); // No note. 108 P1.swap(P2); // No note. 109 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 110 // expected-note@-1{{Dereference of null smart pointer 'P'}} 111 } 112 113 void noNoteTagsForNonMatchingBugType() { 114 std::unique_ptr<A> P; // No note. 115 std::unique_ptr<A> P1; // No note. 116 P1 = std::move(P); // expected-note {{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} 117 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' of type 'std::unique_ptr' [cplusplus.Move]}} 118 // expected-note@-1 {{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} 119 } 120