blob: bff6907809c11271bad6dd2f6d7d72c0b7c4cce5 [file] [log] [blame]
Jordan Roseaea020f2013-01-26 01:28:23 +00001// 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
Jordan Roseaea020f2013-01-26 01:28:23 +00004namespace rdar12676053 {
5 // Delta-reduced from a preprocessed file.
6 template<class T>
7 class RefCount {
8 T *ref;
9 public:
10 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 {
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 };
Jordan Rose801916b2013-03-01 19:45:10 +000032}
33
34
35// This is the standard placement new.
36inline void* operator new(__typeof__(sizeof(int)), void* __p) throw()
37{
38 return __p;
39}
40
41extern bool coin();
42
Jordan Roseecaa7d22013-03-15 21:41:46 +000043class SomeClass {
44public:
45 void doSomething();
46};
47
Jordan Rose801916b2013-03-01 19:45:10 +000048namespace References {
49 class Map {
50 int *&getNewBox();
51 int *firstBox;
52
53 public:
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
64 int *&getValueIndirectly(int key) {
65 int *&valueBox = getValue(key);
66 return valueBox;
67 }
68 };
69
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);
Jordan Rose08821c82013-03-22 21:15:26 +000087 box2 = 0;
88 *box2 = 1; // expected-warning {{Dereference of null pointer}}
Jordan Rose801916b2013-03-01 19:45:10 +000089 }
90
Jordan Rose801916b2013-03-01 19:45:10 +000091 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
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 }
Jordan Roseb41977f2013-03-07 01:23:25 +0000115
116 SomeClass *getNull() {
117 return 0;
118 }
119
120 SomeClass &returnNullReference() {
121 SomeClass *x = getNull();
122 return *x;
123#ifndef SUPPRESSED
124 // expected-warning@-2 {{Returning null reference}}
125#endif
126 }
Jordan Rose801916b2013-03-01 19:45:10 +0000127}
Anna Zakse9989bd2013-03-13 20:20:14 +0000128
129class X{
130public:
131 void get();
132};
133
134X *getNull() {
135 return 0;
136}
137
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
145void test1() {
146 return deref1(getNull());
147}
148
149void deref2(X *p3) {
150 p3->get();
151 #ifndef SUPPRESSED
152 // expected-warning@-2 {{Called C++ object pointer is null}}
153 #endif
154}
155
156void pass2(X *const &p2) {
157 deref2(p2);
158}
159
160void test2() {
161 pass2(getNull());
162}
163
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
172void test3() {
173 deref3(getNull());
174}
175
176
Jordan Roseecaa7d22013-03-15 21:41:46 +0000177namespace Cleanups {
178 class NonTrivial {
179 public:
180 ~NonTrivial();
181
182 SomeClass *getNull() {
183 return 0;
184 }
185 };
186
187 void testImmediate() {
188 NonTrivial().getNull()->doSomething();
189#ifndef SUPPRESSED
190 // expected-warning@-2 {{Called C++ object pointer is null}}
191#endif
192 }
193
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
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
209 void testArgument() {
210 testArgumentHelper(NonTrivial().getNull());
211 }
212}