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