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)36 inline 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()134 X *getNull() {
135 	return 0;
136 }
137 
deref1(X * const & p)138 void 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()145 void test1() {
146 	return deref1(getNull());
147 }
148 
deref2(X * p3)149 void 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)156 void pass2(X *const &p2) {
157 	deref2(p2);
158 }
159 
test2()160 void test2() {
161 	pass2(getNull());
162 }
163 
deref3(X * const & p2)164 void 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()172 void 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