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