xref: /aosp_15_r20/external/clang/test/Analysis/misc-ps-region-store.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
3*67e74705SXin Li 
4*67e74705SXin Li void clang_analyzer_warnIfReached();
5*67e74705SXin Li 
6*67e74705SXin Li // Test basic handling of references.
7*67e74705SXin Li char &test1_aux();
test1()8*67e74705SXin Li char *test1() {
9*67e74705SXin Li   return &test1_aux();
10*67e74705SXin Li }
11*67e74705SXin Li 
12*67e74705SXin Li // Test test1_aux() evaluates to char &.
test1_as_rvalue()13*67e74705SXin Li char test1_as_rvalue() {
14*67e74705SXin Li   return test1_aux();
15*67e74705SXin Li }
16*67e74705SXin Li 
17*67e74705SXin Li // Test passing a value as a reference.  The 'const' in test2_aux() adds
18*67e74705SXin Li // an ImplicitCastExpr, which is evaluated as an lvalue.
19*67e74705SXin Li int test2_aux(const int &n);
test2(int n)20*67e74705SXin Li int test2(int n) {
21*67e74705SXin Li   return test2_aux(n);
22*67e74705SXin Li }
23*67e74705SXin Li 
24*67e74705SXin Li int test2_b_aux(const short &n);
test2_b(int n)25*67e74705SXin Li int test2_b(int n) {
26*67e74705SXin Li   return test2_b_aux(n);
27*67e74705SXin Li }
28*67e74705SXin Li 
29*67e74705SXin Li // Test getting the lvalue of a derived and converting it to a base.  This
30*67e74705SXin Li // previously crashed.
31*67e74705SXin Li class Test3_Base {};
32*67e74705SXin Li class Test3_Derived : public Test3_Base {};
33*67e74705SXin Li 
34*67e74705SXin Li int test3_aux(Test3_Base &x);
test3(Test3_Derived x)35*67e74705SXin Li int test3(Test3_Derived x) {
36*67e74705SXin Li   return test3_aux(x);
37*67e74705SXin Li }
38*67e74705SXin Li 
39*67e74705SXin Li //===---------------------------------------------------------------------===//
40*67e74705SXin Li // Test CFG support for C++ condition variables.
41*67e74705SXin Li //===---------------------------------------------------------------------===//
42*67e74705SXin Li 
43*67e74705SXin Li int test_init_in_condition_aux();
test_init_in_condition()44*67e74705SXin Li int test_init_in_condition() {
45*67e74705SXin Li   if (int x = test_init_in_condition_aux()) { // no-warning
46*67e74705SXin Li     return 1;
47*67e74705SXin Li   }
48*67e74705SXin Li   return 0;
49*67e74705SXin Li }
50*67e74705SXin Li 
test_init_in_condition_switch()51*67e74705SXin Li int test_init_in_condition_switch() {
52*67e74705SXin Li   switch (int x = test_init_in_condition_aux()) { // no-warning
53*67e74705SXin Li     case 1:
54*67e74705SXin Li       return 0;
55*67e74705SXin Li     case 2:
56*67e74705SXin Li       if (x == 2)
57*67e74705SXin Li         return 0;
58*67e74705SXin Li       else {
59*67e74705SXin Li         clang_analyzer_warnIfReached();  // unreachable
60*67e74705SXin Li       }
61*67e74705SXin Li     default:
62*67e74705SXin Li       break;
63*67e74705SXin Li   }
64*67e74705SXin Li   return 0;
65*67e74705SXin Li }
66*67e74705SXin Li 
test_init_in_condition_while()67*67e74705SXin Li int test_init_in_condition_while() {
68*67e74705SXin Li   int z = 0;
69*67e74705SXin Li   while (int x = ++z) { // no-warning
70*67e74705SXin Li     if (x == 2)
71*67e74705SXin Li       break;
72*67e74705SXin Li   }
73*67e74705SXin Li 
74*67e74705SXin Li   if (z == 2)
75*67e74705SXin Li     return 0;
76*67e74705SXin Li 
77*67e74705SXin Li   clang_analyzer_warnIfReached();  // unreachable
78*67e74705SXin Li   return 0;
79*67e74705SXin Li }
80*67e74705SXin Li 
81*67e74705SXin Li 
test_init_in_condition_for()82*67e74705SXin Li int test_init_in_condition_for() {
83*67e74705SXin Li   int z = 0;
84*67e74705SXin Li   for (int x = 0; int y = ++z; ++x) {
85*67e74705SXin Li     if (x == y) // no-warning
86*67e74705SXin Li       break;
87*67e74705SXin Li   }
88*67e74705SXin Li   if (z == 1)
89*67e74705SXin Li     return 0;
90*67e74705SXin Li 
91*67e74705SXin Li   clang_analyzer_warnIfReached();  // unreachable
92*67e74705SXin Li   return 0;
93*67e74705SXin Li }
94*67e74705SXin Li 
95*67e74705SXin Li //===---------------------------------------------------------------------===//
96*67e74705SXin Li // Test handling of 'this' pointer.
97*67e74705SXin Li //===---------------------------------------------------------------------===//
98*67e74705SXin Li 
99*67e74705SXin Li class TestHandleThis {
100*67e74705SXin Li   int x;
101*67e74705SXin Li 
102*67e74705SXin Li   TestHandleThis();
103*67e74705SXin Li   int foo();
104*67e74705SXin Li   int null_deref_negative();
105*67e74705SXin Li   int null_deref_positive();
106*67e74705SXin Li };
107*67e74705SXin Li 
foo()108*67e74705SXin Li int TestHandleThis::foo() {
109*67e74705SXin Li   // Assume that 'x' is initialized.
110*67e74705SXin Li   return x + 1; // no-warning
111*67e74705SXin Li }
112*67e74705SXin Li 
null_deref_negative()113*67e74705SXin Li int TestHandleThis::null_deref_negative() {
114*67e74705SXin Li   x = 10;
115*67e74705SXin Li   if (x == 10) {
116*67e74705SXin Li     return 1;
117*67e74705SXin Li   }
118*67e74705SXin Li   clang_analyzer_warnIfReached();  // unreachable
119*67e74705SXin Li   return 0;
120*67e74705SXin Li }
121*67e74705SXin Li 
null_deref_positive()122*67e74705SXin Li int TestHandleThis::null_deref_positive() {
123*67e74705SXin Li   x = 10;
124*67e74705SXin Li   if (x == 9) {
125*67e74705SXin Li     return 1;
126*67e74705SXin Li   }
127*67e74705SXin Li   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
128*67e74705SXin Li   return 0;
129*67e74705SXin Li }
130*67e74705SXin Li 
131*67e74705SXin Li // PR 7675 - passing literals by-reference
132*67e74705SXin Li void pr7675(const double &a);
133*67e74705SXin Li void pr7675(const int &a);
134*67e74705SXin Li void pr7675(const char &a);
135*67e74705SXin Li void pr7675_i(const _Complex double &a);
136*67e74705SXin Li 
pr7675_test()137*67e74705SXin Li void pr7675_test() {
138*67e74705SXin Li   pr7675(10.0);
139*67e74705SXin Li   pr7675(10);
140*67e74705SXin Li   pr7675('c');
141*67e74705SXin Li   pr7675_i(4.0i);
142*67e74705SXin Li 
143*67e74705SXin Li   // Add check to ensure we are analyzing the code up to this point.
144*67e74705SXin Li   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
145*67e74705SXin Li }
146*67e74705SXin Li 
147*67e74705SXin Li // <rdar://problem/8375510> - CFGBuilder should handle temporaries.
148*67e74705SXin Li struct R8375510 {
149*67e74705SXin Li   R8375510();
150*67e74705SXin Li   ~R8375510();
151*67e74705SXin Li   R8375510 operator++(int);
152*67e74705SXin Li };
153*67e74705SXin Li 
r8375510(R8375510 x,R8375510 y)154*67e74705SXin Li int r8375510(R8375510 x, R8375510 y) {
155*67e74705SXin Li   for (; ; x++) { }
156*67e74705SXin Li }
157*67e74705SXin Li 
158*67e74705SXin Li // PR8419 -- this used to crash.
159*67e74705SXin Li 
160*67e74705SXin Li class String8419 {
161*67e74705SXin Li  public:
162*67e74705SXin Li   char& get(int n);
163*67e74705SXin Li   char& operator[](int n);
164*67e74705SXin Li };
165*67e74705SXin Li 
166*67e74705SXin Li char& get8419();
167*67e74705SXin Li 
Test8419()168*67e74705SXin Li void Test8419() {
169*67e74705SXin Li   String8419 s;
170*67e74705SXin Li   ++(s.get(0));
171*67e74705SXin Li   get8419()--;  // used to crash
172*67e74705SXin Li   --s[0];       // used to crash
173*67e74705SXin Li   s[0] &= 1;    // used to crash
174*67e74705SXin Li   s[0]++;       // used to crash
175*67e74705SXin Li }
176*67e74705SXin Li 
177*67e74705SXin Li // PR8426 -- this used to crash.
178*67e74705SXin Li 
179*67e74705SXin Li void Use(void* to);
180*67e74705SXin Li 
181*67e74705SXin Li template <class T> class Foo {
182*67e74705SXin Li   ~Foo();
183*67e74705SXin Li   struct Bar;
184*67e74705SXin Li   Bar* bar_;
185*67e74705SXin Li };
186*67e74705SXin Li 
~Foo()187*67e74705SXin Li template <class T> Foo<T>::~Foo() {
188*67e74705SXin Li   Use(bar_);
189*67e74705SXin Li   T::DoSomething();
190*67e74705SXin Li   bar_->Work();
191*67e74705SXin Li }
192*67e74705SXin Li 
193*67e74705SXin Li // PR8427 -- this used to crash.
194*67e74705SXin Li 
195*67e74705SXin Li class Dummy {};
196*67e74705SXin Li 
197*67e74705SXin Li bool operator==(Dummy, int);
198*67e74705SXin Li 
199*67e74705SXin Li template <typename T>
200*67e74705SXin Li class Foo2 {
201*67e74705SXin Li   bool Bar();
202*67e74705SXin Li };
203*67e74705SXin Li 
204*67e74705SXin Li template <typename T>
Bar()205*67e74705SXin Li bool Foo2<T>::Bar() {
206*67e74705SXin Li   return 0 == T();
207*67e74705SXin Li }
208*67e74705SXin Li 
209*67e74705SXin Li // PR8433 -- this used to crash.
210*67e74705SXin Li 
211*67e74705SXin Li template <typename T>
212*67e74705SXin Li class Foo3 {
213*67e74705SXin Li  public:
214*67e74705SXin Li   void Bar();
215*67e74705SXin Li   void Baz();
216*67e74705SXin Li   T value_;
217*67e74705SXin Li };
218*67e74705SXin Li 
219*67e74705SXin Li template <typename T>
Bar()220*67e74705SXin Li void Foo3<T>::Bar() {
221*67e74705SXin Li   Baz();
222*67e74705SXin Li   value_();
223*67e74705SXin Li }
224*67e74705SXin Li 
225*67e74705SXin Li //===---------------------------------------------------------------------===//
226*67e74705SXin Li // Handle misc. C++ constructs.
227*67e74705SXin Li //===---------------------------------------------------------------------===//
228*67e74705SXin Li 
229*67e74705SXin Li namespace fum {
230*67e74705SXin Li   int i = 3;
231*67e74705SXin Li };
232*67e74705SXin Li 
test_namespace()233*67e74705SXin Li void test_namespace() {
234*67e74705SXin Li   // Previously triggered a crash.
235*67e74705SXin Li   using namespace fum;
236*67e74705SXin Li   int x = i;
237*67e74705SXin Li }
238*67e74705SXin Li 
239*67e74705SXin Li // Test handling methods that accept references as parameters, and that
240*67e74705SXin Li // variables are properly invalidated.
241*67e74705SXin Li class RDar9203355 {
242*67e74705SXin Li   bool foo(unsigned valA, long long &result) const;
243*67e74705SXin Li   bool foo(unsigned valA, int &result) const;
244*67e74705SXin Li };
foo(unsigned valA,int & result) const245*67e74705SXin Li bool RDar9203355::foo(unsigned valA, int &result) const {
246*67e74705SXin Li   long long val;
247*67e74705SXin Li   if (foo(valA, val) ||
248*67e74705SXin Li       (int)val != val) // no-warning
249*67e74705SXin Li     return true;
250*67e74705SXin Li   result = val; // no-warning
251*67e74705SXin Li   return false;
252*67e74705SXin Li }
253*67e74705SXin Li 
254*67e74705SXin Li // Test handling of new[].
rdar9212512()255*67e74705SXin Li void rdar9212512() {
256*67e74705SXin Li   int *x = new int[10];
257*67e74705SXin Li   for (unsigned i = 0 ; i < 2 ; ++i) {
258*67e74705SXin Li     // This previously triggered an uninitialized values warning.
259*67e74705SXin Li     x[i] = 1;  // no-warning
260*67e74705SXin Li   }
261*67e74705SXin Li }
262*67e74705SXin Li 
263*67e74705SXin Li // Test basic support for dynamic_cast<>.
264*67e74705SXin Li struct Rdar9212495_C { virtual void bar() const; };
265*67e74705SXin Li class Rdar9212495_B : public Rdar9212495_C {};
266*67e74705SXin Li class Rdar9212495_A : public Rdar9212495_B {};
rdar9212495(const Rdar9212495_C * ptr)267*67e74705SXin Li const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {
268*67e74705SXin Li   const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);
269*67e74705SXin Li 
270*67e74705SXin Li   // This is not valid C++; dynamic_cast with a reference type will throw an
271*67e74705SXin Li   // exception if the pointer does not match the expected type. However, our
272*67e74705SXin Li   // implementation of dynamic_cast will pass through a null pointer...or a
273*67e74705SXin Li   // "null reference"! So this branch is actually possible.
274*67e74705SXin Li   if (&val == 0) {
275*67e74705SXin Li     val.bar(); // expected-warning{{Called C++ object pointer is null}}
276*67e74705SXin Li   }
277*67e74705SXin Li 
278*67e74705SXin Li   return val;
279*67e74705SXin Li }
280*67e74705SXin Li 
rdar9212495_ptr(const Rdar9212495_C * ptr)281*67e74705SXin Li const Rdar9212495_A* rdar9212495_ptr(const Rdar9212495_C* ptr) {
282*67e74705SXin Li   const Rdar9212495_A* val = dynamic_cast<const Rdar9212495_A*>(ptr);
283*67e74705SXin Li 
284*67e74705SXin Li   if (val == 0) {
285*67e74705SXin Li     val->bar(); // expected-warning{{Called C++ object pointer is null}}
286*67e74705SXin Li   }
287*67e74705SXin Li 
288*67e74705SXin Li   return val;
289*67e74705SXin Li }
290*67e74705SXin Li 
291*67e74705SXin Li // Test constructors invalidating arguments.  Previously this raised
292*67e74705SXin Li // an uninitialized value warning.
293*67e74705SXin Li extern "C" void __attribute__((noreturn)) PR9645_exit(int i);
294*67e74705SXin Li 
295*67e74705SXin Li class PR9645_SideEffect
296*67e74705SXin Li {
297*67e74705SXin Li public:
298*67e74705SXin Li   PR9645_SideEffect(int *pi); // caches pi in i_
299*67e74705SXin Li   void Read(int *pi); // copies *pi into *i_
300*67e74705SXin Li private:
301*67e74705SXin Li   int *i_;
302*67e74705SXin Li };
303*67e74705SXin Li 
PR9645()304*67e74705SXin Li void PR9645() {
305*67e74705SXin Li   int i;
306*67e74705SXin Li 
307*67e74705SXin Li   PR9645_SideEffect se(&i);
308*67e74705SXin Li   int j = 1;
309*67e74705SXin Li   se.Read(&j); // this has a side-effect of initializing i.
310*67e74705SXin Li 
311*67e74705SXin Li   PR9645_exit(i); // no-warning
312*67e74705SXin Li }
313*67e74705SXin Li 
PR9645_SideEffect(int * pi)314*67e74705SXin Li PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}
Read(int * pi)315*67e74705SXin Li void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }
316*67e74705SXin Li 
317*67e74705SXin Li // Invalidate fields during C++ method calls.
318*67e74705SXin Li class RDar9267815 {
319*67e74705SXin Li   int x;
320*67e74705SXin Li   void test();
321*67e74705SXin Li   void test_pos();
322*67e74705SXin Li   void test2();
323*67e74705SXin Li   void invalidate();
324*67e74705SXin Li };
325*67e74705SXin Li 
test_pos()326*67e74705SXin Li void RDar9267815::test_pos() {
327*67e74705SXin Li   if (x == 42)
328*67e74705SXin Li     return;
329*67e74705SXin Li   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
330*67e74705SXin Li }
test()331*67e74705SXin Li void RDar9267815::test() {
332*67e74705SXin Li   if (x == 42)
333*67e74705SXin Li     return;
334*67e74705SXin Li   if (x == 42)
335*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
336*67e74705SXin Li }
337*67e74705SXin Li 
test2()338*67e74705SXin Li void RDar9267815::test2() {
339*67e74705SXin Li   if (x == 42)
340*67e74705SXin Li     return;
341*67e74705SXin Li   invalidate();
342*67e74705SXin Li   if (x == 42)
343*67e74705SXin Li     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
344*67e74705SXin Li }
345*67e74705SXin Li 
346*67e74705SXin Li // Test reference parameters.
347*67e74705SXin Li void test_ref_double_aux(double &Value);
test_ref_double()348*67e74705SXin Li float test_ref_double() {
349*67e74705SXin Li   double dVal;
350*67e74705SXin Li   test_ref_double_aux(dVal);
351*67e74705SXin Li   // This previously warned because 'dVal' was thought to be uninitialized.
352*67e74705SXin Li   float Val = (float)dVal; // no-warning
353*67e74705SXin Li   return Val;
354*67e74705SXin Li }
355*67e74705SXin Li 
356*67e74705SXin Li // Test invalidation of class fields.
357*67e74705SXin Li class TestInvalidateClass {
358*67e74705SXin Li public:
359*67e74705SXin Li   int x;
360*67e74705SXin Li };
361*67e74705SXin Li 
362*67e74705SXin Li void test_invalidate_class_aux(TestInvalidateClass &x);
363*67e74705SXin Li 
test_invalidate_class()364*67e74705SXin Li int test_invalidate_class() {
365*67e74705SXin Li   TestInvalidateClass y;
366*67e74705SXin Li   test_invalidate_class_aux(y);
367*67e74705SXin Li   return y.x; // no-warning
368*67e74705SXin Li }
369*67e74705SXin Li 
370*67e74705SXin Li // Test correct pointer arithmetic using 'p--'.  This is to warn that we
371*67e74705SXin Li // were loading beyond the written characters in buf.
RDar9269695(char * dst,unsigned int n)372*67e74705SXin Li char *RDar9269695(char *dst, unsigned int n)
373*67e74705SXin Li {
374*67e74705SXin Li   char buff[40], *p;
375*67e74705SXin Li 
376*67e74705SXin Li   p = buff;
377*67e74705SXin Li   do
378*67e74705SXin Li     *p++ = '0' + n % 10;
379*67e74705SXin Li   while (n /= 10);
380*67e74705SXin Li 
381*67e74705SXin Li   do
382*67e74705SXin Li     *dst++ = *--p; // no-warning
383*67e74705SXin Li   while (p != buff);
384*67e74705SXin Li 
385*67e74705SXin Li   return dst;
386*67e74705SXin Li }
387*67e74705SXin Li 
388*67e74705SXin Li // Test that we invalidate byref arguments passed to constructors.
389*67e74705SXin Li class TestInvalidateInCtor {
390*67e74705SXin Li public:
391*67e74705SXin Li   TestInvalidateInCtor(unsigned &x);
392*67e74705SXin Li };
393*67e74705SXin Li 
test_invalidate_in_ctor()394*67e74705SXin Li unsigned test_invalidate_in_ctor() {
395*67e74705SXin Li   unsigned x;
396*67e74705SXin Li   TestInvalidateInCtor foo(x);
397*67e74705SXin Li   return x; // no-warning
398*67e74705SXin Li }
test_invalidate_in_ctor_new()399*67e74705SXin Li unsigned test_invalidate_in_ctor_new() {
400*67e74705SXin Li   unsigned x;
401*67e74705SXin Li   delete (new TestInvalidateInCtor(x));
402*67e74705SXin Li   return x; // no-warning
403*67e74705SXin Li }
404*67e74705SXin Li 
405*67e74705SXin Li // Test assigning into a symbolic offset.
406*67e74705SXin Li struct TestAssignIntoSymbolicOffset {
407*67e74705SXin Li   int **stuff[100];
408*67e74705SXin Li   void test(int x, int y);
409*67e74705SXin Li };
410*67e74705SXin Li 
test(int x,int y)411*67e74705SXin Li void TestAssignIntoSymbolicOffset::test(int x, int y) {
412*67e74705SXin Li   x--;
413*67e74705SXin Li   if (x > 8 || x < 0)
414*67e74705SXin Li     return;
415*67e74705SXin Li   if (stuff[x])
416*67e74705SXin Li     return;
417*67e74705SXin Li   if (!stuff[x]) {
418*67e74705SXin Li     stuff[x] = new int*[y+1];
419*67e74705SXin Li     // Previously triggered a null dereference.
420*67e74705SXin Li     stuff[x][y] = 0; // no-warning
421*67e74705SXin Li   }
422*67e74705SXin Li }
423*67e74705SXin Li 
424*67e74705SXin Li // Test loads from static fields.  This previously triggered an uninitialized
425*67e74705SXin Li // value warning.
426*67e74705SXin Li class ClassWithStatic {
427*67e74705SXin Li public:
428*67e74705SXin Li     static const unsigned value = 1;
429*67e74705SXin Li };
430*67e74705SXin Li 
rdar9948787_negative()431*67e74705SXin Li int rdar9948787_negative() {
432*67e74705SXin Li     ClassWithStatic classWithStatic;
433*67e74705SXin Li     unsigned value = classWithStatic.value;
434*67e74705SXin Li     if (value == 1)
435*67e74705SXin Li       return 1;
436*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
437*67e74705SXin Li     return 0;
438*67e74705SXin Li }
439*67e74705SXin Li 
rdar9948787_positive()440*67e74705SXin Li int rdar9948787_positive() {
441*67e74705SXin Li     ClassWithStatic classWithStatic;
442*67e74705SXin Li     unsigned value = classWithStatic.value;
443*67e74705SXin Li     if (value == 0)
444*67e74705SXin Li       return 1;
445*67e74705SXin Li     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
446*67e74705SXin Li     return 0;
447*67e74705SXin Li }
448*67e74705SXin Li 
449*67e74705SXin Li // Regression test against global constants and switches.
450*67e74705SXin Li enum rdar10202899_ValT { rdar10202899_ValTA, rdar10202899_ValTB, rdar10202899_ValTC };
451*67e74705SXin Li const rdar10202899_ValT val = rdar10202899_ValTA;
rdar10202899_test1()452*67e74705SXin Li void rdar10202899_test1() {
453*67e74705SXin Li   switch (val) {
454*67e74705SXin Li     case rdar10202899_ValTA: {}
455*67e74705SXin Li   };
456*67e74705SXin Li }
457*67e74705SXin Li 
rdar10202899_test2()458*67e74705SXin Li void rdar10202899_test2() {
459*67e74705SXin Li   if (val == rdar10202899_ValTA)
460*67e74705SXin Li    return;
461*67e74705SXin Li   clang_analyzer_warnIfReached();  // no-warning
462*67e74705SXin Li }
463*67e74705SXin Li 
rdar10202899_test3()464*67e74705SXin Li void rdar10202899_test3() {
465*67e74705SXin Li   switch (val) {
466*67e74705SXin Li     case rdar10202899_ValTA: return;
467*67e74705SXin Li     default: ;
468*67e74705SXin Li   };
469*67e74705SXin Li   clang_analyzer_warnIfReached();  // no-warning
470*67e74705SXin Li }
471*67e74705SXin Li 
472*67e74705SXin Li // This used to crash the analyzer because of the unnamed bitfield.
PR11249()473*67e74705SXin Li void PR11249()
474*67e74705SXin Li {
475*67e74705SXin Li   struct {
476*67e74705SXin Li     char f1:4;
477*67e74705SXin Li     char   :4;
478*67e74705SXin Li     char f2[1];
479*67e74705SXin Li     char f3;
480*67e74705SXin Li   } V = { 1, {2}, 3 };
481*67e74705SXin Li   if (V.f1 != 1)
482*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
483*67e74705SXin Li   if (V.f2[0] != 2)
484*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
485*67e74705SXin Li   if (V.f3 != 3)
486*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
487*67e74705SXin Li }
488*67e74705SXin Li 
489*67e74705SXin Li // Handle doing a load from the memory associated with the code for
490*67e74705SXin Li // a function.
491*67e74705SXin Li extern double nan( const char * );
PR11450()492*67e74705SXin Li double PR11450() {
493*67e74705SXin Li   double NaN = *(double*) nan;
494*67e74705SXin Li   return NaN;
495*67e74705SXin Li }
496*67e74705SXin Li 
497*67e74705SXin Li // Test that 'this' is assumed non-null upon analyzing the entry to a "top-level"
498*67e74705SXin Li // function (i.e., when not analyzing from a specific caller).
499*67e74705SXin Li struct TestNullThis {
500*67e74705SXin Li   int field;
501*67e74705SXin Li   void test();
502*67e74705SXin Li };
503*67e74705SXin Li 
test()504*67e74705SXin Li void TestNullThis::test() {
505*67e74705SXin Li   int *p = &field;
506*67e74705SXin Li   if (p)
507*67e74705SXin Li     return;
508*67e74705SXin Li   field = 2; // no-warning
509*67e74705SXin Li }
510*67e74705SXin Li 
511*67e74705SXin Li // Test handling of 'catch' exception variables, and not warning
512*67e74705SXin Li // about uninitialized values.
513*67e74705SXin Li enum MyEnum { MyEnumValue };
rdar10892489()514*67e74705SXin Li MyEnum rdar10892489() {
515*67e74705SXin Li   try {
516*67e74705SXin Li       throw MyEnumValue;
517*67e74705SXin Li   } catch (MyEnum e) {
518*67e74705SXin Li       return e; // no-warning
519*67e74705SXin Li   }
520*67e74705SXin Li   return MyEnumValue;
521*67e74705SXin Li }
522*67e74705SXin Li 
rdar10892489_positive()523*67e74705SXin Li MyEnum rdar10892489_positive() {
524*67e74705SXin Li   try {
525*67e74705SXin Li     throw MyEnumValue;
526*67e74705SXin Li   } catch (MyEnum e) {
527*67e74705SXin Li     int *p = 0;
528*67e74705SXin Li     // FALSE NEGATIVE
529*67e74705SXin Li     *p = 0xDEADBEEF; // {{null}}
530*67e74705SXin Li     return e;
531*67e74705SXin Li   }
532*67e74705SXin Li   return MyEnumValue;
533*67e74705SXin Li }
534*67e74705SXin Li 
535*67e74705SXin Li // Test handling of catch with no condition variable.
PR11545()536*67e74705SXin Li void PR11545() {
537*67e74705SXin Li   try
538*67e74705SXin Li   {
539*67e74705SXin Li       throw;
540*67e74705SXin Li   }
541*67e74705SXin Li   catch (...)
542*67e74705SXin Li   {
543*67e74705SXin Li   }
544*67e74705SXin Li }
545*67e74705SXin Li 
PR11545_positive()546*67e74705SXin Li void PR11545_positive() {
547*67e74705SXin Li   try
548*67e74705SXin Li   {
549*67e74705SXin Li       throw;
550*67e74705SXin Li   }
551*67e74705SXin Li   catch (...)
552*67e74705SXin Li   {
553*67e74705SXin Li     int *p = 0;
554*67e74705SXin Li     // FALSE NEGATIVE
555*67e74705SXin Li     *p = 0xDEADBEEF; // {{null}}
556*67e74705SXin Li   }
557*67e74705SXin Li }
558*67e74705SXin Li 
559*67e74705SXin Li // Test handling taking the address of a field.  While the analyzer
560*67e74705SXin Li // currently doesn't do anything intelligent here, this previously
561*67e74705SXin Li // resulted in a crash.
562*67e74705SXin Li class PR11146 {
563*67e74705SXin Li public:
564*67e74705SXin Li   struct Entry;
565*67e74705SXin Li   void baz();
566*67e74705SXin Li };
567*67e74705SXin Li 
568*67e74705SXin Li struct PR11146::Entry {
569*67e74705SXin Li   int x;
570*67e74705SXin Li };
571*67e74705SXin Li 
baz()572*67e74705SXin Li void PR11146::baz() {
573*67e74705SXin Li   (void) &Entry::x;
574*67e74705SXin Li }
575*67e74705SXin Li 
576*67e74705SXin Li // Test symbolicating a reference.  In this example, the
577*67e74705SXin Li // analyzer (originally) didn't know how to handle x[index - index2],
578*67e74705SXin Li // returning an UnknownVal.  The conjured symbol wasn't a location,
579*67e74705SXin Li // and would result in a crash.
rdar10924675(unsigned short x[],int index,int index2)580*67e74705SXin Li void rdar10924675(unsigned short x[], int index, int index2) {
581*67e74705SXin Li   unsigned short &y = x[index - index2];
582*67e74705SXin Li   if (y == 0)
583*67e74705SXin Li     return;
584*67e74705SXin Li }
585*67e74705SXin Li 
586*67e74705SXin Li // Test handling CXXScalarValueInitExprs.
rdar11401827()587*67e74705SXin Li void rdar11401827() {
588*67e74705SXin Li   int x = int();
589*67e74705SXin Li   if (!x) {
590*67e74705SXin Li     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
591*67e74705SXin Li     ; // Suppress warning that both branches are identical
592*67e74705SXin Li   }
593*67e74705SXin Li   else {
594*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
595*67e74705SXin Li   }
596*67e74705SXin Li }
597*67e74705SXin Li 
598*67e74705SXin Li //===---------------------------------------------------------------------===//
599*67e74705SXin Li // Handle inlining of C++ method calls.
600*67e74705SXin Li //===---------------------------------------------------------------------===//
601*67e74705SXin Li 
602*67e74705SXin Li struct A {
603*67e74705SXin Li   int *p;
fooA604*67e74705SXin Li   void foo(int *q) {
605*67e74705SXin Li     p = q;
606*67e74705SXin Li   }
barA607*67e74705SXin Li   void bar() {
608*67e74705SXin Li     *p = 0; // expected-warning {{null pointer}}
609*67e74705SXin Li   }
610*67e74705SXin Li };
611*67e74705SXin Li 
test_inline()612*67e74705SXin Li void test_inline() {
613*67e74705SXin Li   A a;
614*67e74705SXin Li   a.foo(0);
615*67e74705SXin Li   a.bar();
616*67e74705SXin Li }
617*67e74705SXin Li 
test_alloca_in_a_recursive_function(int p1)618*67e74705SXin Li void test_alloca_in_a_recursive_function(int p1) {
619*67e74705SXin Li     __builtin_alloca (p1);
620*67e74705SXin Li     test_alloca_in_a_recursive_function(1);
621*67e74705SXin Li     test_alloca_in_a_recursive_function(2);
622*67e74705SXin Li }
623*67e74705SXin Li 
624*67e74705SXin Li //===---------------------------------------------------------------------===//
625*67e74705SXin Li // Random tests.
626*67e74705SXin Li //===---------------------------------------------------------------------===//
627*67e74705SXin Li 
628*67e74705SXin Li // Tests assigning using a C-style initializer to a struct
629*67e74705SXin Li // variable whose sub-field is also a struct.  This currently
630*67e74705SXin Li // results in a CXXTempObjectRegion being created, but not
631*67e74705SXin Li // properly handled.  For now, we just ignore that value
632*67e74705SXin Li // to avoid a crash (<rdar://problem/12753384>).
633*67e74705SXin Li struct RDar12753384_ClassA {
634*67e74705SXin Li   unsigned z;
635*67e74705SXin Li };
636*67e74705SXin Li struct  RDar12753384_ClassB {
637*67e74705SXin Li   unsigned x;
638*67e74705SXin Li   RDar12753384_ClassA y[ 8 ] ;
639*67e74705SXin Li };
RDar12753384()640*67e74705SXin Li unsigned RDar12753384() {
641*67e74705SXin Li   RDar12753384_ClassB w = { 0x00 };
642*67e74705SXin Li   RDar12753384_ClassA y[8];
643*67e74705SXin Li   return w.x;
644*67e74705SXin Li }
645*67e74705SXin Li 
646*67e74705SXin Li // This testcase tests whether we treat the anonymous union and union
647*67e74705SXin Li // the same way.  This previously resulted in a "return of stack address"
648*67e74705SXin Li // warning because the anonymous union resulting in a temporary object
649*67e74705SXin Li // getting put into the initializer.  We still aren't handling this correctly,
650*67e74705SXin Li // but now if a temporary object appears in an initializer we just ignore it.
651*67e74705SXin Li // Fixes <rdar://problem/12755044>.
652*67e74705SXin Li 
653*67e74705SXin Li struct Rdar12755044_foo
654*67e74705SXin Li {
655*67e74705SXin Li     struct Rdar12755044_bar
656*67e74705SXin Li     {
657*67e74705SXin Li         union baz
658*67e74705SXin Li         {
659*67e74705SXin Li             int   i;
660*67e74705SXin Li         };
661*67e74705SXin Li     } aBar;
662*67e74705SXin Li };
663*67e74705SXin Li 
664*67e74705SXin Li struct Rdar12755044_foo_anon
665*67e74705SXin Li {
666*67e74705SXin Li     struct Rdar12755044_bar
667*67e74705SXin Li     {
668*67e74705SXin Li         union
669*67e74705SXin Li         {
670*67e74705SXin Li             int   i;
671*67e74705SXin Li         };
672*67e74705SXin Li     } aBar;
673*67e74705SXin Li };
674*67e74705SXin Li 
radar12755044_anon()675*67e74705SXin Li const Rdar12755044_foo_anon *radar12755044_anon() {
676*67e74705SXin Li   static const Rdar12755044_foo_anon Rdar12755044_foo_list[] = { { { } } };
677*67e74705SXin Li   return Rdar12755044_foo_list; // no-warning
678*67e74705SXin Li }
679*67e74705SXin Li 
radar12755044()680*67e74705SXin Li const Rdar12755044_foo *radar12755044() {
681*67e74705SXin Li   static const Rdar12755044_foo Rdar12755044_foo_list[] = { { { } } };
682*67e74705SXin Li   return Rdar12755044_foo_list; // no-warning
683*67e74705SXin Li }
684*67e74705SXin Li 
685*67e74705SXin Li // Test the correct handling of integer to bool conversions.  Previously
686*67e74705SXin Li // this resulted in a false positive because integers were being truncated
687*67e74705SXin Li // and not tested for non-zero.
rdar12759044()688*67e74705SXin Li void rdar12759044() {
689*67e74705SXin Li   int flag = 512;
690*67e74705SXin Li   if (!(flag & 512)) {
691*67e74705SXin Li     clang_analyzer_warnIfReached();  // no-warning
692*67e74705SXin Li   }
693*67e74705SXin Li }
694*67e74705SXin Li 
695*67e74705SXin Li // The analyzer currently does not model complex types.  Test that the load
696*67e74705SXin Li // from 'x' is not flagged as being uninitialized.
697*67e74705SXin Li typedef __complex__ float _ComplexT;
rdar12964481(_ComplexT * y)698*67e74705SXin Li void rdar12964481(_ComplexT *y) {
699*67e74705SXin Li    _ComplexT x;
700*67e74705SXin Li    __real__ x = 1.0;
701*67e74705SXin Li    __imag__ x = 1.0;
702*67e74705SXin Li    *y *= x; // no-warning
703*67e74705SXin Li }
rdar12964481_b(_ComplexT * y)704*67e74705SXin Li void rdar12964481_b(_ComplexT *y) {
705*67e74705SXin Li    _ComplexT x;
706*67e74705SXin Li    // Eventually this should be a warning.
707*67e74705SXin Li    *y *= x; // no-warning
708*67e74705SXin Li }
709*67e74705SXin Li 
710*67e74705SXin Li // Test case for PR 12921.  This previously produced
711*67e74705SXin Li // a bogus warning.
712*67e74705SXin Li static const int pr12921_arr[] = { 0, 1 };
713*67e74705SXin Li static const int pr12921_arrcount = sizeof(pr12921_arr)/sizeof(int);
714*67e74705SXin Li 
pr12921(int argc,char ** argv)715*67e74705SXin Li int pr12921(int argc, char **argv) {
716*67e74705SXin Li   int i, retval;
717*67e74705SXin Li   for (i = 0; i < pr12921_arrcount; i++) {
718*67e74705SXin Li     if (argc == i) {
719*67e74705SXin Li       retval = i;
720*67e74705SXin Li       break;
721*67e74705SXin Li     }
722*67e74705SXin Li   }
723*67e74705SXin Li 
724*67e74705SXin Li   // No match
725*67e74705SXin Li   if (i == pr12921_arrcount) return 66;
726*67e74705SXin Li   return pr12921_arr[retval];
727*67e74705SXin Li }
728*67e74705SXin Li 
729