1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection\ 2 // RUN: -analyzer-checker cplusplus.Move,alpha.cplusplus.SmartPtr\ 3 // RUN: -analyzer-config cplusplus.SmartPtrModeling:ModelSmartPtrDereference=true\ 4 // RUN: -std=c++11 -verify %s 5 6 #include "Inputs/system-header-simulator-cxx.h" 7 8 void clang_analyzer_warnIfReached(); 9 void clang_analyzer_numTimesReached(); 10 11 void derefAfterMove(std::unique_ptr<int> P) { 12 std::unique_ptr<int> Q = std::move(P); 13 if (Q) 14 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} 15 *Q.get() = 1; // no-warning 16 if (P) 17 clang_analyzer_warnIfReached(); // no-warning 18 // TODO: Report a null dereference (instead). 19 *P.get() = 1; // expected-warning {{Method called on moved-from object 'P'}} 20 } 21 22 // Don't crash when attempting to model a call with unknown callee. 23 namespace testUnknownCallee { 24 struct S { 25 void foo(); 26 }; 27 void bar(S *s, void (S::*func)(void)) { 28 (s->*func)(); // no-crash 29 } 30 } // namespace testUnknownCallee 31 32 class A { 33 public: 34 A(){}; 35 void foo(); 36 }; 37 38 A *return_null() { 39 return nullptr; 40 } 41 42 void derefAfterValidCtr() { 43 std::unique_ptr<A> P(new A()); 44 P->foo(); // No warning. 45 } 46 47 void derefOfUnknown(std::unique_ptr<A> P) { 48 P->foo(); // No warning. 49 } 50 51 void derefAfterDefaultCtr() { 52 std::unique_ptr<A> P; 53 P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 54 } 55 56 void derefAfterCtrWithNull() { 57 std::unique_ptr<A> P(nullptr); 58 *P; // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 59 } 60 61 void derefAfterCtrWithNullReturnMethod() { 62 std::unique_ptr<A> P(return_null()); 63 P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 64 } 65 66 void derefAfterRelease() { 67 std::unique_ptr<A> P(new A()); 68 P.release(); 69 clang_analyzer_numTimesReached(); // expected-warning {{1}} 70 P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 71 } 72 73 void derefAfterReset() { 74 std::unique_ptr<A> P(new A()); 75 P.reset(); 76 clang_analyzer_numTimesReached(); // expected-warning {{1}} 77 P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 78 } 79 80 void derefAfterResetWithNull() { 81 std::unique_ptr<A> P(new A()); 82 P.reset(nullptr); 83 P->foo(); // expected-warning {{Dereference of null smart pointer [alpha.cplusplus.SmartPtr]}} 84 } 85 86 void derefAfterResetWithNonNull() { 87 std::unique_ptr<A> P; 88 P.reset(new A()); 89 P->foo(); // No warning. 90 } 91 92 void derefAfterReleaseAndResetWithNonNull() { 93 std::unique_ptr<A> P(new A()); 94 P.release(); 95 P.reset(new A()); 96 P->foo(); // No warning. 97 } 98 99 void derefOnReleasedNullRawPtr() { 100 std::unique_ptr<A> P; 101 A *AP = P.release(); 102 AP->foo(); // expected-warning {{Called C++ object pointer is null [core.CallAndMessage]}} 103 } 104