1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s 2*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s 3*67e74705SXin Li 4*67e74705SXin Li namespace rdar12676053 { 5*67e74705SXin Li // Delta-reduced from a preprocessed file. 6*67e74705SXin Li template<class T> 7*67e74705SXin Li class RefCount { 8*67e74705SXin Li T *ref; 9*67e74705SXin Li public: operator ->() const10*67e74705SXin Li T *operator->() const { 11*67e74705SXin Li return ref ? ref : 0; 12*67e74705SXin Li } 13*67e74705SXin Li }; 14*67e74705SXin Li 15*67e74705SXin Li class string {}; 16*67e74705SXin Li 17*67e74705SXin Li class ParserInputState { 18*67e74705SXin Li public: 19*67e74705SXin Li string filename; 20*67e74705SXin Li }; 21*67e74705SXin Li 22*67e74705SXin Li class Parser { setFilename(const string & f)23*67e74705SXin Li void setFilename(const string& f) { 24*67e74705SXin Li inputState->filename = f; 25*67e74705SXin Li #ifndef SUPPRESSED 26*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 27*67e74705SXin Li #endif 28*67e74705SXin Li } 29*67e74705SXin Li protected: 30*67e74705SXin Li RefCount<ParserInputState> inputState; 31*67e74705SXin Li }; 32*67e74705SXin Li } 33*67e74705SXin Li 34*67e74705SXin Li 35*67e74705SXin Li // This is the standard placement new. operator new(__typeof__(sizeof (int)) ,void * __p)36*67e74705SXin Liinline void* operator new(__typeof__(sizeof(int)), void* __p) throw() 37*67e74705SXin Li { 38*67e74705SXin Li return __p; 39*67e74705SXin Li } 40*67e74705SXin Li 41*67e74705SXin Li extern bool coin(); 42*67e74705SXin Li 43*67e74705SXin Li class SomeClass { 44*67e74705SXin Li public: 45*67e74705SXin Li void doSomething(); 46*67e74705SXin Li }; 47*67e74705SXin Li 48*67e74705SXin Li namespace References { 49*67e74705SXin Li class Map { 50*67e74705SXin Li int *&getNewBox(); 51*67e74705SXin Li int *firstBox; 52*67e74705SXin Li 53*67e74705SXin Li public: getValue(int key)54*67e74705SXin Li int *&getValue(int key) { 55*67e74705SXin Li if (coin()) { 56*67e74705SXin Li return firstBox; 57*67e74705SXin Li } else { 58*67e74705SXin Li int *&newBox = getNewBox(); 59*67e74705SXin Li newBox = 0; 60*67e74705SXin Li return newBox; 61*67e74705SXin Li } 62*67e74705SXin Li } 63*67e74705SXin Li getValueIndirectly(int key)64*67e74705SXin Li int *&getValueIndirectly(int key) { 65*67e74705SXin Li int *&valueBox = getValue(key); 66*67e74705SXin Li return valueBox; 67*67e74705SXin Li } 68*67e74705SXin Li }; 69*67e74705SXin Li testMap(Map & m,int i)70*67e74705SXin Li void testMap(Map &m, int i) { 71*67e74705SXin Li *m.getValue(i) = 1; 72*67e74705SXin Li #ifndef SUPPRESSED 73*67e74705SXin Li // expected-warning@-2 {{Dereference of null pointer}} 74*67e74705SXin Li #endif 75*67e74705SXin Li 76*67e74705SXin Li *m.getValueIndirectly(i) = 1; 77*67e74705SXin Li #ifndef SUPPRESSED 78*67e74705SXin Li // expected-warning@-2 {{Dereference of null pointer}} 79*67e74705SXin Li #endif 80*67e74705SXin Li 81*67e74705SXin Li int *&box = m.getValue(i); 82*67e74705SXin Li extern int *getPointer(); 83*67e74705SXin Li box = getPointer(); 84*67e74705SXin Li *box = 1; // no-warning 85*67e74705SXin Li 86*67e74705SXin Li int *&box2 = m.getValue(i); 87*67e74705SXin Li box2 = 0; 88*67e74705SXin Li *box2 = 1; // expected-warning {{Dereference of null pointer}} 89*67e74705SXin Li } 90*67e74705SXin Li getSomeClass()91*67e74705SXin Li SomeClass *&getSomeClass() { 92*67e74705SXin Li if (coin()) { 93*67e74705SXin Li extern SomeClass *&opaqueClass(); 94*67e74705SXin Li return opaqueClass(); 95*67e74705SXin Li } else { 96*67e74705SXin Li static SomeClass *sharedClass; 97*67e74705SXin Li sharedClass = 0; 98*67e74705SXin Li return sharedClass; 99*67e74705SXin Li } 100*67e74705SXin Li } 101*67e74705SXin Li testClass()102*67e74705SXin Li void testClass() { 103*67e74705SXin Li getSomeClass()->doSomething(); 104*67e74705SXin Li #ifndef SUPPRESSED 105*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 106*67e74705SXin Li #endif 107*67e74705SXin Li 108*67e74705SXin Li // Separate the lvalue-to-rvalue conversion from the subsequent dereference. 109*67e74705SXin Li SomeClass *object = getSomeClass(); 110*67e74705SXin Li object->doSomething(); 111*67e74705SXin Li #ifndef SUPPRESSED 112*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 113*67e74705SXin Li #endif 114*67e74705SXin Li } 115*67e74705SXin Li getNull()116*67e74705SXin Li SomeClass *getNull() { 117*67e74705SXin Li return 0; 118*67e74705SXin Li } 119*67e74705SXin Li returnNullReference()120*67e74705SXin Li SomeClass &returnNullReference() { 121*67e74705SXin Li SomeClass *x = getNull(); 122*67e74705SXin Li return *x; 123*67e74705SXin Li #ifndef SUPPRESSED 124*67e74705SXin Li // expected-warning@-2 {{Returning null reference}} 125*67e74705SXin Li #endif 126*67e74705SXin Li } 127*67e74705SXin Li } 128*67e74705SXin Li 129*67e74705SXin Li class X{ 130*67e74705SXin Li public: 131*67e74705SXin Li void get(); 132*67e74705SXin Li }; 133*67e74705SXin Li getNull()134*67e74705SXin LiX *getNull() { 135*67e74705SXin Li return 0; 136*67e74705SXin Li } 137*67e74705SXin Li deref1(X * const & p)138*67e74705SXin Livoid deref1(X *const &p) { 139*67e74705SXin Li return p->get(); 140*67e74705SXin Li #ifndef SUPPRESSED 141*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 142*67e74705SXin Li #endif 143*67e74705SXin Li } 144*67e74705SXin Li test1()145*67e74705SXin Livoid test1() { 146*67e74705SXin Li return deref1(getNull()); 147*67e74705SXin Li } 148*67e74705SXin Li deref2(X * p3)149*67e74705SXin Livoid deref2(X *p3) { 150*67e74705SXin Li p3->get(); 151*67e74705SXin Li #ifndef SUPPRESSED 152*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 153*67e74705SXin Li #endif 154*67e74705SXin Li } 155*67e74705SXin Li pass2(X * const & p2)156*67e74705SXin Livoid pass2(X *const &p2) { 157*67e74705SXin Li deref2(p2); 158*67e74705SXin Li } 159*67e74705SXin Li test2()160*67e74705SXin Livoid test2() { 161*67e74705SXin Li pass2(getNull()); 162*67e74705SXin Li } 163*67e74705SXin Li deref3(X * const & p2)164*67e74705SXin Livoid deref3(X *const &p2) { 165*67e74705SXin Li X *p3 = p2; 166*67e74705SXin Li p3->get(); 167*67e74705SXin Li #ifndef SUPPRESSED 168*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 169*67e74705SXin Li #endif 170*67e74705SXin Li } 171*67e74705SXin Li test3()172*67e74705SXin Livoid test3() { 173*67e74705SXin Li deref3(getNull()); 174*67e74705SXin Li } 175*67e74705SXin Li 176*67e74705SXin Li 177*67e74705SXin Li namespace Cleanups { 178*67e74705SXin Li class NonTrivial { 179*67e74705SXin Li public: 180*67e74705SXin Li ~NonTrivial(); 181*67e74705SXin Li getNull()182*67e74705SXin Li SomeClass *getNull() { 183*67e74705SXin Li return 0; 184*67e74705SXin Li } 185*67e74705SXin Li }; 186*67e74705SXin Li testImmediate()187*67e74705SXin Li void testImmediate() { 188*67e74705SXin Li NonTrivial().getNull()->doSomething(); 189*67e74705SXin Li #ifndef SUPPRESSED 190*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 191*67e74705SXin Li #endif 192*67e74705SXin Li } 193*67e74705SXin Li testAssignment()194*67e74705SXin Li void testAssignment() { 195*67e74705SXin Li SomeClass *ptr = NonTrivial().getNull(); 196*67e74705SXin Li ptr->doSomething(); 197*67e74705SXin Li #ifndef SUPPRESSED 198*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 199*67e74705SXin Li #endif 200*67e74705SXin Li } 201*67e74705SXin Li testArgumentHelper(SomeClass * arg)202*67e74705SXin Li void testArgumentHelper(SomeClass *arg) { 203*67e74705SXin Li arg->doSomething(); 204*67e74705SXin Li #ifndef SUPPRESSED 205*67e74705SXin Li // expected-warning@-2 {{Called C++ object pointer is null}} 206*67e74705SXin Li #endif 207*67e74705SXin Li } 208*67e74705SXin Li testArgument()209*67e74705SXin Li void testArgument() { 210*67e74705SXin Li testArgumentHelper(NonTrivial().getNull()); 211*67e74705SXin Li } 212*67e74705SXin Li } 213