// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s namespace rdar12676053 { // Delta-reduced from a preprocessed file. template<class T> class RefCount { T *ref; public: T *operator->() const { return ref ? ref : 0; } }; class string {}; class ParserInputState { public: string filename; }; class Parser { void setFilename(const string& f) { inputState->filename = f; #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } protected: RefCount<ParserInputState> inputState; }; } // This is the standard placement new. inline void* operator new(__typeof__(sizeof(int)), void* __p) throw() { return __p; } extern bool coin(); class SomeClass { public: void doSomething(); }; namespace References { class Map { int *&getNewBox(); int *firstBox; public: int *&getValue(int key) { if (coin()) { return firstBox; } else { int *&newBox = getNewBox(); newBox = 0; return newBox; } } int *&getValueIndirectly(int key) { int *&valueBox = getValue(key); return valueBox; } }; void testMap(Map &m, int i) { *m.getValue(i) = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif *m.getValueIndirectly(i) = 1; #ifndef SUPPRESSED // expected-warning@-2 {{Dereference of null pointer}} #endif int *&box = m.getValue(i); extern int *getPointer(); box = getPointer(); *box = 1; // no-warning int *&box2 = m.getValue(i); box2 = 0; *box2 = 1; // expected-warning {{Dereference of null pointer}} } SomeClass *&getSomeClass() { if (coin()) { extern SomeClass *&opaqueClass(); return opaqueClass(); } else { static SomeClass *sharedClass; sharedClass = 0; return sharedClass; } } void testClass() { getSomeClass()->doSomething(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif // Separate the lvalue-to-rvalue conversion from the subsequent dereference. SomeClass *object = getSomeClass(); object->doSomething(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } SomeClass *getNull() { return 0; } SomeClass &returnNullReference() { SomeClass *x = getNull(); return *x; #ifndef SUPPRESSED // expected-warning@-2 {{Returning null reference}} #endif } } class X{ public: void get(); }; X *getNull() { return 0; } void deref1(X *const &p) { return p->get(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void test1() { return deref1(getNull()); } void deref2(X *p3) { p3->get(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void pass2(X *const &p2) { deref2(p2); } void test2() { pass2(getNull()); } void deref3(X *const &p2) { X *p3 = p2; p3->get(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void test3() { deref3(getNull()); } namespace Cleanups { class NonTrivial { public: ~NonTrivial(); SomeClass *getNull() { return 0; } }; void testImmediate() { NonTrivial().getNull()->doSomething(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void testAssignment() { SomeClass *ptr = NonTrivial().getNull(); ptr->doSomething(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void testArgumentHelper(SomeClass *arg) { arg->doSomething(); #ifndef SUPPRESSED // expected-warning@-2 {{Called C++ object pointer is null}} #endif } void testArgument() { testArgumentHelper(NonTrivial().getNull()); } }