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()); // expected-note {{Smart pointer 'P' is constructed}} 40 // FIXME: should mark region as uninteresting after release, so above note will not be there 41 P.release(); // expected-note {{Smart pointer 'P' is released and set to null}} 42 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 43 // expected-note@-1{{Dereference of null smart pointer 'P'}} 44 } 45 46 void derefAfterReset() { 47 std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}} 48 P.reset(); // expected-note {{Smart pointer 'P' reset using a null value}} 49 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 50 // expected-note@-1{{Dereference of null smart pointer 'P'}} 51 } 52 53 void derefAfterResetWithNull() { 54 A *NullInnerPtr = nullptr; // expected-note {{'NullInnerPtr' initialized to a null pointer value}} 55 std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}} 56 P.reset(NullInnerPtr); // expected-note {{Smart pointer 'P' reset using a null value}} 57 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 58 // expected-note@-1{{Dereference of null smart pointer 'P'}} 59 } 60 61 // FIXME: Fix this test when support is added for tracking raw pointer 62 // and mark the smart pointer as interesting based on that and add tags. 63 void derefOnReleasedNullRawPtr() { 64 std::unique_ptr<A> P; // FIXME: add note "Default constructed smart pointer 'P' is null" 65 A *AP = P.release(); // expected-note {{'AP' initialized to a null pointer value}} 66 AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} 67 // expected-note@-1{{Called C++ object pointer is null}} 68 } 69 70 void derefOnSwappedNullPtr() { 71 std::unique_ptr<A> P(new A()); // expected-note {{Smart pointer 'P' is constructed}} 72 std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}} 73 P.swap(PNull); // expected-note {{Swapped null smart pointer 'PNull' with smart pointer 'P'}} 74 PNull->foo(); // No warning. 75 (*P).foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 76 // expected-note@-1{{Dereference of null smart pointer 'P'}} 77 } 78 79 // FIXME: Fix this test when "std::swap" is modeled seperately. 80 void derefOnStdSwappedNullPtr() { 81 std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}} 82 std::unique_ptr<A> PNull; // expected-note {{Default constructed smart pointer 'PNull' is null}} 83 std::swap(P, PNull); // expected-note@Inputs/system-header-simulator-cxx.h:978 {{Swapped null smart pointer 'PNull' with smart pointer 'P'}} 84 // expected-note@-1 {{Calling 'swap<A>'}} 85 // expected-note@-2 {{Returning from 'swap<A>'}} 86 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 87 // expected-note@-1{{Dereference of null smart pointer 'P'}} 88 } 89 90 struct StructWithSmartPtr { // expected-note {{Default constructed smart pointer 'S.P' is null}} 91 std::unique_ptr<A> P; 92 }; 93 94 void derefAfterDefaultCtrInsideStruct() { 95 StructWithSmartPtr S; // expected-note {{Calling implicit default constructor for 'StructWithSmartPtr'}} 96 // expected-note@-1 {{Returning from default constructor for 'StructWithSmartPtr'}} 97 S.P->foo(); // expected-warning {{Dereference of null smart pointer 'S.P' [alpha.cplusplus.SmartPtr]}} 98 // expected-note@-1{{Dereference of null smart pointer 'S.P'}} 99 } 100 101 void noNoteTagsForNonInterestingRegion() { 102 std::unique_ptr<A> P; // expected-note {{Default constructed smart pointer 'P' is null}} 103 std::unique_ptr<A> P1; // No note. 104 std::unique_ptr<A> P2; // No note. 105 P1.release(); // No note. 106 P1.reset(); // No note. 107 P1.swap(P2); // No note. 108 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' [alpha.cplusplus.SmartPtr]}} 109 // expected-note@-1{{Dereference of null smart pointer 'P'}} 110 } 111 112 void noNoteTagsForNonMatchingBugType() { 113 std::unique_ptr<A> P; // No note. 114 std::unique_ptr<A> P1; // No note. 115 P1 = std::move(P); // expected-note {{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}} 116 P->foo(); // expected-warning {{Dereference of null smart pointer 'P' of type 'std::unique_ptr' [cplusplus.Move]}} 117 // expected-note@-1 {{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}} 118 } 119