blob: 37153f76506294fec207eaa4c37b1bb9a870185f [file] [log] [blame]
Ted Kremenek033a07e2011-08-03 23:14:55 +00001// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
2// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
Ted Kremenekd87682e2009-12-17 01:44:13 +00003
Ted Kremenek53287512009-12-18 20:13:39 +00004// Test basic handling of references.
Ted Kremenekd87682e2009-12-17 01:44:13 +00005char &test1_aux();
6char *test1() {
7 return &test1_aux();
8}
Ted Kremenek53287512009-12-18 20:13:39 +00009
Zhongxing Xu910e4082009-12-19 03:17:55 +000010// Test test1_aux() evaluates to char &.
Ted Kremenek53287512009-12-18 20:13:39 +000011char test1_as_rvalue() {
12 return test1_aux();
13}
14
Ted Kremenek949bdb42009-12-23 00:26:16 +000015// Test passing a value as a reference. The 'const' in test2_aux() adds
16// an ImplicitCastExpr, which is evaluated as an lvalue.
17int test2_aux(const int &n);
18int test2(int n) {
19 return test2_aux(n);
20}
21
22int test2_b_aux(const short &n);
23int test2_b(int n) {
24 return test2_b_aux(n);
25}
Ted Kremenek077a40d2009-12-23 01:19:20 +000026
27// Test getting the lvalue of a derived and converting it to a base. This
28// previously crashed.
29class Test3_Base {};
30class Test3_Derived : public Test3_Base {};
31
32int test3_aux(Test3_Base &x);
33int test3(Test3_Derived x) {
34 return test3_aux(x);
35}
36
Ted Kremenekde0d2632010-01-05 02:18:06 +000037//===---------------------------------------------------------------------===//
38// Test CFG support for C++ condition variables.
39//===---------------------------------------------------------------------===//
40
Ted Kremenek61dfbec2009-12-23 04:49:01 +000041int test_init_in_condition_aux();
42int test_init_in_condition() {
43 if (int x = test_init_in_condition_aux()) { // no-warning
44 return 1;
45 }
46 return 0;
47}
Ted Kremenekfcfb5032009-12-24 00:40:03 +000048
49int test_init_in_condition_switch() {
50 switch (int x = test_init_in_condition_aux()) { // no-warning
51 case 1:
52 return 0;
53 case 2:
54 if (x == 2)
55 return 0;
56 else {
57 // Unreachable.
58 int *p = 0;
59 *p = 0xDEADBEEF; // no-warning
60 }
61 default:
62 break;
63 }
64 return 0;
65}
Ted Kremenek4c508a12009-12-24 00:54:56 +000066
67int test_init_in_condition_while() {
Ted Kremenek4ec010a2009-12-24 01:34:10 +000068 int z = 0;
69 while (int x = ++z) { // no-warning
70 if (x == 2)
Ted Kremenek4c508a12009-12-24 00:54:56 +000071 break;
Ted Kremenek4c508a12009-12-24 00:54:56 +000072 }
Ted Kremenek4ec010a2009-12-24 01:34:10 +000073
74 if (z == 2)
75 return 0;
76
77 int *p = 0;
78 *p = 0xDEADBEEF; // no-warning
Ted Kremenek4c508a12009-12-24 00:54:56 +000079 return 0;
80}
Ted Kremenek4ec010a2009-12-24 01:34:10 +000081
Ted Kremenekdd8b4412009-12-24 02:41:19 +000082
83int test_init_in_condition_for() {
84 int z = 0;
85 for (int x = 0; int y = ++z; ++x) {
86 if (x == y) // no-warning
87 break;
88 }
89 if (z == 1)
90 return 0;
91
92 int *p = 0;
93 *p = 0xDEADBEEF; // no-warning
94 return 0;
95}
Ted Kremenekde0d2632010-01-05 02:18:06 +000096
97//===---------------------------------------------------------------------===//
98// Test handling of 'this' pointer.
99//===---------------------------------------------------------------------===//
100
101class TestHandleThis {
102 int x;
103
104 TestHandleThis();
105 int foo();
106 int null_deref_negative();
107 int null_deref_positive();
108};
109
110int TestHandleThis::foo() {
111 // Assume that 'x' is initialized.
112 return x + 1; // no-warning
113}
114
115int TestHandleThis::null_deref_negative() {
116 x = 10;
117 if (x == 10) {
118 return 1;
119 }
120 int *p = 0;
121 *p = 0xDEADBEEF; // no-warning
122 return 0;
123}
124
125int TestHandleThis::null_deref_positive() {
126 x = 10;
127 if (x == 9) {
128 return 1;
129 }
130 int *p = 0;
131 *p = 0xDEADBEEF; // expected-warning{{null pointer}}
132 return 0;
133}
134
Ted Kremenek741b9be2010-07-29 01:31:59 +0000135// PR 7675 - passing literals by-reference
136void pr7675(const double &a);
137void pr7675(const int &a);
138void pr7675(const char &a);
139void pr7675_i(const _Complex double &a);
140
141void pr7675_test() {
142 pr7675(10.0);
143 pr7675(10);
144 pr7675('c');
145 pr7675_i(4.0i);
146 // Add null deref to ensure we are analyzing the code up to this point.
147 int *p = 0;
148 *p = 0xDEADBEEF; // expected-warning{{null pointer}}
149}
150
Ted Kremeneka427f1d2010-08-31 18:47:34 +0000151// <rdar://problem/8375510> - CFGBuilder should handle temporaries.
152struct R8375510 {
153 R8375510();
154 ~R8375510();
155 R8375510 operator++(int);
156};
157
158int r8375510(R8375510 x, R8375510 y) {
159 for (; ; x++) { }
160}
161
Zhanyong Wan99cae5b2010-11-22 08:45:56 +0000162// PR8419 -- this used to crash.
163
164class String8419 {
165 public:
166 char& get(int n);
167 char& operator[](int n);
168};
169
170char& get8419();
171
172void Test8419() {
173 String8419 s;
174 ++(s.get(0));
175 get8419()--; // used to crash
176 --s[0]; // used to crash
177 s[0] &= 1; // used to crash
178 s[0]++; // used to crash
179}
180
Zhanyong Wan739830d2010-10-31 04:22:34 +0000181// PR8426 -- this used to crash.
182
183void Use(void* to);
184
185template <class T> class Foo {
186 ~Foo();
187 struct Bar;
188 Bar* bar_;
189};
190
191template <class T> Foo<T>::~Foo() {
192 Use(bar_);
193 T::DoSomething();
194 bar_->Work();
195}
196
197// PR8427 -- this used to crash.
198
199class Dummy {};
200
201bool operator==(Dummy, int);
202
203template <typename T>
204class Foo2 {
205 bool Bar();
206};
207
208template <typename T>
209bool Foo2<T>::Bar() {
210 return 0 == T();
211}
212
213// PR8433 -- this used to crash.
214
215template <typename T>
216class Foo3 {
217 public:
218 void Bar();
219 void Baz();
220 T value_;
221};
222
223template <typename T>
224void Foo3<T>::Bar() {
225 Baz();
226 value_();
227}
Ted Kremenekb8b07b12011-02-14 17:00:16 +0000228
229//===---------------------------------------------------------------------===//
230// Handle misc. C++ constructs.
231//===---------------------------------------------------------------------===//
232
233namespace fum {
234 int i = 3;
235};
236
237void test_namespace() {
238 // Previously triggered a crash.
239 using namespace fum;
240 int x = i;
241}
242
Ted Kremenekb2771592011-03-30 17:41:19 +0000243// Test handling methods that accept references as parameters, and that
244// variables are properly invalidated.
245class RDar9203355 {
246 bool foo(unsigned valA, long long &result) const;
247 bool foo(unsigned valA, int &result) const;
248};
249bool RDar9203355::foo(unsigned valA, int &result) const {
250 long long val;
251 if (foo(valA, val) ||
252 (int)val != val) // no-warning
253 return true;
254 result = val; // no-warning
255 return false;
256}
257
Ted Kremenek41c5f492011-03-31 04:04:48 +0000258// Test handling of new[].
259void rdar9212512() {
260 int *x = new int[10];
261 for (unsigned i = 0 ; i < 2 ; ++i) {
262 // This previously triggered an uninitialized values warning.
263 x[i] = 1; // no-warning
264 }
265}
Ted Kremenekb2771592011-03-30 17:41:19 +0000266
Ted Kremenek94ae8fd2011-03-31 04:46:53 +0000267// Test basic support for dynamic_cast<>.
268struct Rdar9212495_C { virtual void bar() const; };
269class Rdar9212495_B : public Rdar9212495_C {};
270class Rdar9212495_A : public Rdar9212495_B {};
271const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {
272 const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);
273
274 if (&val == 0) {
275 val.bar(); // FIXME: This should eventually be a null dereference.
276 }
277
278 return val;
279}
280
Ted Kremenek5fe98722011-04-08 22:42:35 +0000281// Test constructors invalidating arguments. Previously this raised
282// an uninitialized value warning.
283extern "C" void __attribute__((noreturn)) PR9645_exit(int i);
284
285class PR9645_SideEffect
286{
287public:
288 PR9645_SideEffect(int *pi); // caches pi in i_
289 void Read(int *pi); // copies *pi into *i_
290private:
291 int *i_;
292};
293
294void PR9645() {
295 int i;
296
297 PR9645_SideEffect se(&i);
298 int j = 1;
299 se.Read(&j); // this has a side-effect of initializing i.
300
301 PR9645_exit(i); // no-warning
302}
303
304PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}
305void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000306
307// Invalidate fields during C++ method calls.
308class RDar9267815 {
309 int x;
310 void test();
311 void test_pos();
312 void test2();
313 void invalidate();
314};
315
316void RDar9267815::test_pos() {
317 int *p = 0;
318 if (x == 42)
319 return;
320 *p = 0xDEADBEEF; // expected-warning {{null}}
321}
322void RDar9267815::test() {
323 int *p = 0;
324 if (x == 42)
325 return;
326 if (x == 42)
327 *p = 0xDEADBEEF; // no-warning
328}
329
330void RDar9267815::test2() {
331 int *p = 0;
332 if (x == 42)
333 return;
334 invalidate();
335 if (x == 42)
336 *p = 0xDEADBEEF; // expected-warning {{null}}
337}
338
Ted Kremenek235c02f2011-04-12 00:28:12 +0000339// Test reference parameters.
340void test_ref_double_aux(double &Value);
341float test_ref_double() {
342 double dVal;
343 test_ref_double_aux(dVal);
344 // This previously warned because 'dVal' was thought to be uninitialized.
345 float Val = (float)dVal; // no-warning
346 return Val;
347}
348
Ted Kremenekbf1a6672011-04-12 00:44:31 +0000349// Test invalidation of class fields.
350class TestInvalidateClass {
351public:
352 int x;
353};
354
355void test_invalidate_class_aux(TestInvalidateClass &x);
356
357int test_invalidate_class() {
358 TestInvalidateClass y;
359 test_invalidate_class_aux(y);
360 return y.x; // no-warning
361}
362
Ted Kremenek3bab50b2011-04-12 03:49:37 +0000363// Test correct pointer arithmetic using 'p--'. This is to warn that we
364// were loading beyond the written characters in buf.
365char *RDar9269695(char *dst, unsigned int n)
366{
367 char buff[40], *p;
368
369 p = buff;
370 do
371 *p++ = '0' + n % 10;
372 while (n /= 10);
373
374 do
375 *dst++ = *--p; // no-warning
376 while (p != buff);
377
378 return dst;
379}
380
Ted Kremenek9d5d3082011-04-12 05:12:39 +0000381// Test that we invalidate byref arguments passed to constructors.
382class TestInvalidateInCtor {
383public:
384 TestInvalidateInCtor(unsigned &x);
385};
386
387unsigned test_invalidate_in_ctor() {
388 unsigned x;
389 TestInvalidateInCtor foo(x);
390 return x; // no-warning
391}
392unsigned test_invalidate_in_ctor_new() {
393 unsigned x;
394 delete (new TestInvalidateInCtor(x));
395 return x; // no-warning
396}
Ted Kremenek3bab50b2011-04-12 03:49:37 +0000397
Ted Kremenekc46d6412011-05-19 23:37:58 +0000398// Test assigning into a symbolic offset.
399struct TestAssignIntoSymbolicOffset {
400 int **stuff[100];
401 void test(int x, int y);
402};
403
404void TestAssignIntoSymbolicOffset::test(int x, int y) {
405 x--;
406 if (x > 8 || x < 0)
407 return;
408 if (stuff[x])
409 return;
410 if (!stuff[x]) {
411 stuff[x] = new int*[y+1];
412 // Previously triggered a null dereference.
413 stuff[x][y] = 0; // no-warning
414 }
415}
416
Ted Kremenek5bd04952011-08-16 21:37:52 +0000417// Test loads from static fields. This previously triggered an uninitialized
418// value warning.
419class ClassWithStatic {
420public:
421 static const unsigned value = 1;
422};
423
424int rdar9948787_negative() {
425 ClassWithStatic classWithStatic;
426 unsigned value = classWithStatic.value;
427 if (value == 1)
428 return 1;
429 int *p = 0;
430 *p = 0xDEADBEEF; // no-warning
431 return 0;
432}
433
434int rdar9948787_positive() {
435 ClassWithStatic classWithStatic;
436 unsigned value = classWithStatic.value;
437 if (value == 0)
438 return 1;
439 int *p = 0;
440 *p = 0xDEADBEEF; // expected-warning {{null}}
441 return 0;
442}
443
Ted Kremeneke4c66752011-09-30 03:51:54 +0000444// Regression test against global constants and switches.
445enum rdar10202899_ValT { rdar10202899_ValTA, rdar10202899_ValTB, rdar10202899_ValTC };
446const rdar10202899_ValT val = rdar10202899_ValTA;
447void rdar10202899_test1() {
448 switch (val) {
449 case rdar10202899_ValTA: {}
450 };
451}
452
453void rdar10202899_test2() {
454 if (val == rdar10202899_ValTA)
455 return;
456 int *p = 0;
457 *p = 0xDEADBEEF;
458}
459
460void rdar10202899_test3() {
461 switch (val) {
462 case rdar10202899_ValTA: return;
463 default: ;
464 };
465 int *p = 0;
466 *p = 0xDEADBEEF;
467}
468
469