1 // 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
3 
4 // Test basic handling of references.
5 char &test1_aux();
6 char *test1() {
7   return &test1_aux();
8 }
9 
10 // Test test1_aux() evaluates to char &.
11 char test1_as_rvalue() {
12   return test1_aux();
13 }
14 
15 // Test passing a value as a reference.  The 'const' in test2_aux() adds
16 // an ImplicitCastExpr, which is evaluated as an lvalue.
17 int test2_aux(const int &n);
18 int test2(int n) {
19   return test2_aux(n);
20 }
21 
22 int test2_b_aux(const short &n);
23 int test2_b(int n) {
24   return test2_b_aux(n);
25 }
26 
27 // Test getting the lvalue of a derived and converting it to a base.  This
28 // previously crashed.
29 class Test3_Base {};
30 class Test3_Derived : public Test3_Base {};
31 
32 int test3_aux(Test3_Base &x);
33 int test3(Test3_Derived x) {
34   return test3_aux(x);
35 }
36 
37 //===---------------------------------------------------------------------===//
38 // Test CFG support for C++ condition variables.
39 //===---------------------------------------------------------------------===//
40 
41 int test_init_in_condition_aux();
42 int test_init_in_condition() {
43   if (int x = test_init_in_condition_aux()) { // no-warning
44     return 1;
45   }
46   return 0;
47 }
48 
49 int 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 }
66 
67 int test_init_in_condition_while() {
68   int z = 0;
69   while (int x = ++z) { // no-warning
70     if (x == 2)
71       break;
72   }
73 
74   if (z == 2)
75     return 0;
76 
77   int *p = 0;
78   *p = 0xDEADBEEF; // no-warning
79   return 0;
80 }
81 
82 
83 int 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 }
96 
97 //===---------------------------------------------------------------------===//
98 // Test handling of 'this' pointer.
99 //===---------------------------------------------------------------------===//
100 
101 class TestHandleThis {
102   int x;
103 
104   TestHandleThis();
105   int foo();
106   int null_deref_negative();
107   int null_deref_positive();
108 };
109 
110 int TestHandleThis::foo() {
111   // Assume that 'x' is initialized.
112   return x + 1; // no-warning
113 }
114 
115 int 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 
125 int 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 
135 // PR 7675 - passing literals by-reference
136 void pr7675(const double &a);
137 void pr7675(const int &a);
138 void pr7675(const char &a);
139 void pr7675_i(const _Complex double &a);
140 
141 void 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 
151 // <rdar://problem/8375510> - CFGBuilder should handle temporaries.
152 struct R8375510 {
153   R8375510();
154   ~R8375510();
155   R8375510 operator++(int);
156 };
157 
158 int r8375510(R8375510 x, R8375510 y) {
159   for (; ; x++) { }
160 }
161 
162 // PR8419 -- this used to crash.
163 
164 class String8419 {
165  public:
166   char& get(int n);
167   char& operator[](int n);
168 };
169 
170 char& get8419();
171 
172 void 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 
181 // PR8426 -- this used to crash.
182 
183 void Use(void* to);
184 
185 template <class T> class Foo {
186   ~Foo();
187   struct Bar;
188   Bar* bar_;
189 };
190 
191 template <class T> Foo<T>::~Foo() {
192   Use(bar_);
193   T::DoSomething();
194   bar_->Work();
195 }
196 
197 // PR8427 -- this used to crash.
198 
199 class Dummy {};
200 
201 bool operator==(Dummy, int);
202 
203 template <typename T>
204 class Foo2 {
205   bool Bar();
206 };
207 
208 template <typename T>
209 bool Foo2<T>::Bar() {
210   return 0 == T();
211 }
212 
213 // PR8433 -- this used to crash.
214 
215 template <typename T>
216 class Foo3 {
217  public:
218   void Bar();
219   void Baz();
220   T value_;
221 };
222 
223 template <typename T>
224 void Foo3<T>::Bar() {
225   Baz();
226   value_();
227 }
228 
229 //===---------------------------------------------------------------------===//
230 // Handle misc. C++ constructs.
231 //===---------------------------------------------------------------------===//
232 
233 namespace fum {
234   int i = 3;
235 };
236 
237 void test_namespace() {
238   // Previously triggered a crash.
239   using namespace fum;
240   int x = i;
241 }
242 
243 // Test handling methods that accept references as parameters, and that
244 // variables are properly invalidated.
245 class RDar9203355 {
246   bool foo(unsigned valA, long long &result) const;
247   bool foo(unsigned valA, int &result) const;
248 };
249 bool 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 
258 // Test handling of new[].
259 void 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 }
266 
267 // Test basic support for dynamic_cast<>.
268 struct Rdar9212495_C { virtual void bar() const; };
269 class Rdar9212495_B : public Rdar9212495_C {};
270 class Rdar9212495_A : public Rdar9212495_B {};
271 const 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 
281 // Test constructors invalidating arguments.  Previously this raised
282 // an uninitialized value warning.
283 extern "C" void __attribute__((noreturn)) PR9645_exit(int i);
284 
285 class PR9645_SideEffect
286 {
287 public:
288   PR9645_SideEffect(int *pi); // caches pi in i_
289   void Read(int *pi); // copies *pi into *i_
290 private:
291   int *i_;
292 };
293 
294 void 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 
304 PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}
305 void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }
306 
307 // Invalidate fields during C++ method calls.
308 class RDar9267815 {
309   int x;
310   void test();
311   void test_pos();
312   void test2();
313   void invalidate();
314 };
315 
316 void RDar9267815::test_pos() {
317   int *p = 0;
318   if (x == 42)
319     return;
320   *p = 0xDEADBEEF; // expected-warning {{null}}
321 }
322 void RDar9267815::test() {
323   int *p = 0;
324   if (x == 42)
325     return;
326   if (x == 42)
327     *p = 0xDEADBEEF; // no-warning
328 }
329 
330 void 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 
339 // Test reference parameters.
340 void test_ref_double_aux(double &Value);
341 float 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 
349 // Test invalidation of class fields.
350 class TestInvalidateClass {
351 public:
352   int x;
353 };
354 
355 void test_invalidate_class_aux(TestInvalidateClass &x);
356 
357 int test_invalidate_class() {
358   TestInvalidateClass y;
359   test_invalidate_class_aux(y);
360   return y.x; // no-warning
361 }
362 
363 // Test correct pointer arithmetic using 'p--'.  This is to warn that we
364 // were loading beyond the written characters in buf.
365 char *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 
381 // Test that we invalidate byref arguments passed to constructors.
382 class TestInvalidateInCtor {
383 public:
384   TestInvalidateInCtor(unsigned &x);
385 };
386 
387 unsigned test_invalidate_in_ctor() {
388   unsigned x;
389   TestInvalidateInCtor foo(x);
390   return x; // no-warning
391 }
392 unsigned test_invalidate_in_ctor_new() {
393   unsigned x;
394   delete (new TestInvalidateInCtor(x));
395   return x; // no-warning
396 }
397 
398 // Test assigning into a symbolic offset.
399 struct TestAssignIntoSymbolicOffset {
400   int **stuff[100];
401   void test(int x, int y);
402 };
403 
404 void 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 
417 // Test loads from static fields.  This previously triggered an uninitialized
418 // value warning.
419 class ClassWithStatic {
420 public:
421     static const unsigned value = 1;
422 };
423 
424 int 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 
434 int 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 
444 // Regression test against global constants and switches.
445 enum rdar10202899_ValT { rdar10202899_ValTA, rdar10202899_ValTB, rdar10202899_ValTC };
446 const rdar10202899_ValT val = rdar10202899_ValTA;
447 void rdar10202899_test1() {
448   switch (val) {
449     case rdar10202899_ValTA: {}
450   };
451 }
452 
453 void rdar10202899_test2() {
454   if (val == rdar10202899_ValTA)
455    return;
456   int *p = 0;
457   *p = 0xDEADBEEF;
458 }
459 
460 void rdar10202899_test3() {
461   switch (val) {
462     case rdar10202899_ValTA: return;
463     default: ;
464   };
465   int *p = 0;
466   *p = 0xDEADBEEF;
467 }
468 
469 
470