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