blob: af9f7cf838e0edf7232f70e123fb8a97fb07150e [file] [log] [blame]
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001// 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// 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
Jordan Rosed000b852013-10-03 16:57:03 +00003
4void clang_analyzer_warnIfReached();
Ted Kremenekd87682e2009-12-17 01:44:13 +00005
Ted Kremenek53287512009-12-18 20:13:39 +00006// Test basic handling of references.
Ted Kremenekd87682e2009-12-17 01:44:13 +00007char &test1_aux();
8char *test1() {
9 return &test1_aux();
10}
Ted Kremenek53287512009-12-18 20:13:39 +000011
Zhongxing Xu910e4082009-12-19 03:17:55 +000012// Test test1_aux() evaluates to char &.
Ted Kremenek53287512009-12-18 20:13:39 +000013char test1_as_rvalue() {
14 return test1_aux();
15}
16
Ted Kremenek949bdb42009-12-23 00:26:16 +000017// Test passing a value as a reference. The 'const' in test2_aux() adds
18// an ImplicitCastExpr, which is evaluated as an lvalue.
19int test2_aux(const int &n);
20int test2(int n) {
21 return test2_aux(n);
22}
23
24int test2_b_aux(const short &n);
25int test2_b(int n) {
26 return test2_b_aux(n);
27}
Ted Kremenek077a40d2009-12-23 01:19:20 +000028
29// Test getting the lvalue of a derived and converting it to a base. This
30// previously crashed.
31class Test3_Base {};
32class Test3_Derived : public Test3_Base {};
33
34int test3_aux(Test3_Base &x);
35int test3(Test3_Derived x) {
36 return test3_aux(x);
37}
38
Ted Kremenekde0d2632010-01-05 02:18:06 +000039//===---------------------------------------------------------------------===//
40// Test CFG support for C++ condition variables.
41//===---------------------------------------------------------------------===//
42
Ted Kremenek61dfbec2009-12-23 04:49:01 +000043int test_init_in_condition_aux();
44int test_init_in_condition() {
45 if (int x = test_init_in_condition_aux()) { // no-warning
46 return 1;
47 }
48 return 0;
49}
Ted Kremenekfcfb5032009-12-24 00:40:03 +000050
51int test_init_in_condition_switch() {
52 switch (int x = test_init_in_condition_aux()) { // no-warning
53 case 1:
54 return 0;
55 case 2:
56 if (x == 2)
57 return 0;
58 else {
Jordan Rosed000b852013-10-03 16:57:03 +000059 clang_analyzer_warnIfReached(); // unreachable
Ted Kremenekfcfb5032009-12-24 00:40:03 +000060 }
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
Jordan Rosed000b852013-10-03 16:57:03 +000077 clang_analyzer_warnIfReached(); // unreachable
Ted Kremenek4c508a12009-12-24 00:54:56 +000078 return 0;
79}
Ted Kremenek4ec010a2009-12-24 01:34:10 +000080
Ted Kremenekdd8b4412009-12-24 02:41:19 +000081
82int test_init_in_condition_for() {
83 int z = 0;
84 for (int x = 0; int y = ++z; ++x) {
85 if (x == y) // no-warning
86 break;
87 }
88 if (z == 1)
89 return 0;
90
Jordan Rosed000b852013-10-03 16:57:03 +000091 clang_analyzer_warnIfReached(); // unreachable
Ted Kremenekdd8b4412009-12-24 02:41:19 +000092 return 0;
93}
Ted Kremenekde0d2632010-01-05 02:18:06 +000094
95//===---------------------------------------------------------------------===//
96// Test handling of 'this' pointer.
97//===---------------------------------------------------------------------===//
98
99class TestHandleThis {
100 int x;
101
102 TestHandleThis();
103 int foo();
104 int null_deref_negative();
105 int null_deref_positive();
106};
107
108int TestHandleThis::foo() {
109 // Assume that 'x' is initialized.
110 return x + 1; // no-warning
111}
112
113int TestHandleThis::null_deref_negative() {
114 x = 10;
115 if (x == 10) {
116 return 1;
117 }
Jordan Rosed000b852013-10-03 16:57:03 +0000118 clang_analyzer_warnIfReached(); // unreachable
Ted Kremenekde0d2632010-01-05 02:18:06 +0000119 return 0;
120}
121
122int TestHandleThis::null_deref_positive() {
123 x = 10;
124 if (x == 9) {
125 return 1;
126 }
Jordan Rosed000b852013-10-03 16:57:03 +0000127 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Ted Kremenekde0d2632010-01-05 02:18:06 +0000128 return 0;
129}
130
Ted Kremenek741b9be2010-07-29 01:31:59 +0000131// PR 7675 - passing literals by-reference
132void pr7675(const double &a);
133void pr7675(const int &a);
134void pr7675(const char &a);
135void pr7675_i(const _Complex double &a);
136
137void pr7675_test() {
138 pr7675(10.0);
139 pr7675(10);
140 pr7675('c');
141 pr7675_i(4.0i);
Jordan Rosed000b852013-10-03 16:57:03 +0000142
143 // Add check to ensure we are analyzing the code up to this point.
144 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Ted Kremenek741b9be2010-07-29 01:31:59 +0000145}
146
Ted Kremeneka427f1d2010-08-31 18:47:34 +0000147// <rdar://problem/8375510> - CFGBuilder should handle temporaries.
148struct R8375510 {
149 R8375510();
150 ~R8375510();
151 R8375510 operator++(int);
152};
153
154int r8375510(R8375510 x, R8375510 y) {
155 for (; ; x++) { }
156}
157
Zhanyong Wan99cae5b2010-11-22 08:45:56 +0000158// PR8419 -- this used to crash.
159
160class String8419 {
161 public:
162 char& get(int n);
163 char& operator[](int n);
164};
165
166char& get8419();
167
168void Test8419() {
169 String8419 s;
170 ++(s.get(0));
171 get8419()--; // used to crash
172 --s[0]; // used to crash
173 s[0] &= 1; // used to crash
174 s[0]++; // used to crash
175}
176
Zhanyong Wan739830d2010-10-31 04:22:34 +0000177// PR8426 -- this used to crash.
178
179void Use(void* to);
180
181template <class T> class Foo {
182 ~Foo();
183 struct Bar;
184 Bar* bar_;
185};
186
187template <class T> Foo<T>::~Foo() {
188 Use(bar_);
189 T::DoSomething();
190 bar_->Work();
191}
192
193// PR8427 -- this used to crash.
194
195class Dummy {};
196
197bool operator==(Dummy, int);
198
199template <typename T>
200class Foo2 {
201 bool Bar();
202};
203
204template <typename T>
205bool Foo2<T>::Bar() {
206 return 0 == T();
207}
208
209// PR8433 -- this used to crash.
210
211template <typename T>
212class Foo3 {
213 public:
214 void Bar();
215 void Baz();
216 T value_;
217};
218
219template <typename T>
220void Foo3<T>::Bar() {
221 Baz();
222 value_();
223}
Ted Kremenekb8b07b12011-02-14 17:00:16 +0000224
225//===---------------------------------------------------------------------===//
226// Handle misc. C++ constructs.
227//===---------------------------------------------------------------------===//
228
229namespace fum {
230 int i = 3;
231};
232
233void test_namespace() {
234 // Previously triggered a crash.
235 using namespace fum;
236 int x = i;
237}
238
Ted Kremenekb2771592011-03-30 17:41:19 +0000239// Test handling methods that accept references as parameters, and that
240// variables are properly invalidated.
241class RDar9203355 {
242 bool foo(unsigned valA, long long &result) const;
243 bool foo(unsigned valA, int &result) const;
244};
245bool RDar9203355::foo(unsigned valA, int &result) const {
246 long long val;
247 if (foo(valA, val) ||
248 (int)val != val) // no-warning
249 return true;
250 result = val; // no-warning
251 return false;
252}
253
Ted Kremenek41c5f492011-03-31 04:04:48 +0000254// Test handling of new[].
255void rdar9212512() {
256 int *x = new int[10];
257 for (unsigned i = 0 ; i < 2 ; ++i) {
258 // This previously triggered an uninitialized values warning.
259 x[i] = 1; // no-warning
260 }
261}
Ted Kremenekb2771592011-03-30 17:41:19 +0000262
Ted Kremenek94ae8fd2011-03-31 04:46:53 +0000263// Test basic support for dynamic_cast<>.
264struct Rdar9212495_C { virtual void bar() const; };
265class Rdar9212495_B : public Rdar9212495_C {};
266class Rdar9212495_A : public Rdar9212495_B {};
267const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {
268 const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);
269
Jordan Rose9f3b9d52012-08-02 21:33:42 +0000270 // This is not valid C++; dynamic_cast with a reference type will throw an
Jordan Rosea8695182012-08-04 01:04:52 +0000271 // exception if the pointer does not match the expected type. However, our
272 // implementation of dynamic_cast will pass through a null pointer...or a
273 // "null reference"! So this branch is actually possible.
Ted Kremenek94ae8fd2011-03-31 04:46:53 +0000274 if (&val == 0) {
Jordan Rosea8695182012-08-04 01:04:52 +0000275 val.bar(); // expected-warning{{Called C++ object pointer is null}}
Ted Kremenek94ae8fd2011-03-31 04:46:53 +0000276 }
277
278 return val;
279}
280
Jordan Rose9f3b9d52012-08-02 21:33:42 +0000281const Rdar9212495_A* rdar9212495_ptr(const Rdar9212495_C* ptr) {
282 const Rdar9212495_A* val = dynamic_cast<const Rdar9212495_A*>(ptr);
283
284 if (val == 0) {
285 val->bar(); // expected-warning{{Called C++ object pointer is null}}
286 }
287
288 return val;
289}
290
Ted Kremenek5fe98722011-04-08 22:42:35 +0000291// Test constructors invalidating arguments. Previously this raised
292// an uninitialized value warning.
293extern "C" void __attribute__((noreturn)) PR9645_exit(int i);
294
295class PR9645_SideEffect
296{
297public:
298 PR9645_SideEffect(int *pi); // caches pi in i_
299 void Read(int *pi); // copies *pi into *i_
300private:
301 int *i_;
302};
303
304void PR9645() {
305 int i;
306
307 PR9645_SideEffect se(&i);
308 int j = 1;
309 se.Read(&j); // this has a side-effect of initializing i.
310
311 PR9645_exit(i); // no-warning
312}
313
314PR9645_SideEffect::PR9645_SideEffect(int *pi) : i_(pi) {}
315void PR9645_SideEffect::Read(int *pi) { *i_ = *pi; }
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000316
317// Invalidate fields during C++ method calls.
318class RDar9267815 {
319 int x;
320 void test();
321 void test_pos();
322 void test2();
323 void invalidate();
324};
325
326void RDar9267815::test_pos() {
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000327 if (x == 42)
328 return;
Jordan Rosed000b852013-10-03 16:57:03 +0000329 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000330}
331void RDar9267815::test() {
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000332 if (x == 42)
333 return;
334 if (x == 42)
Jordan Rosed000b852013-10-03 16:57:03 +0000335 clang_analyzer_warnIfReached(); // no-warning
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000336}
337
338void RDar9267815::test2() {
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000339 if (x == 42)
340 return;
341 invalidate();
342 if (x == 42)
Jordan Rosed000b852013-10-03 16:57:03 +0000343 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Ted Kremenek9fec9b12011-04-11 22:22:05 +0000344}
345
Ted Kremenek235c02f2011-04-12 00:28:12 +0000346// Test reference parameters.
347void test_ref_double_aux(double &Value);
348float test_ref_double() {
349 double dVal;
350 test_ref_double_aux(dVal);
351 // This previously warned because 'dVal' was thought to be uninitialized.
352 float Val = (float)dVal; // no-warning
353 return Val;
354}
355
Ted Kremenekbf1a6672011-04-12 00:44:31 +0000356// Test invalidation of class fields.
357class TestInvalidateClass {
358public:
359 int x;
360};
361
362void test_invalidate_class_aux(TestInvalidateClass &x);
363
364int test_invalidate_class() {
365 TestInvalidateClass y;
366 test_invalidate_class_aux(y);
367 return y.x; // no-warning
368}
369
Ted Kremenek3bab50b2011-04-12 03:49:37 +0000370// Test correct pointer arithmetic using 'p--'. This is to warn that we
371// were loading beyond the written characters in buf.
372char *RDar9269695(char *dst, unsigned int n)
373{
374 char buff[40], *p;
375
376 p = buff;
377 do
378 *p++ = '0' + n % 10;
379 while (n /= 10);
380
381 do
382 *dst++ = *--p; // no-warning
383 while (p != buff);
384
385 return dst;
386}
387
Ted Kremenek9d5d3082011-04-12 05:12:39 +0000388// Test that we invalidate byref arguments passed to constructors.
389class TestInvalidateInCtor {
390public:
391 TestInvalidateInCtor(unsigned &x);
392};
393
394unsigned test_invalidate_in_ctor() {
395 unsigned x;
396 TestInvalidateInCtor foo(x);
397 return x; // no-warning
398}
399unsigned test_invalidate_in_ctor_new() {
400 unsigned x;
401 delete (new TestInvalidateInCtor(x));
402 return x; // no-warning
403}
Ted Kremenek3bab50b2011-04-12 03:49:37 +0000404
Ted Kremenekc46d6412011-05-19 23:37:58 +0000405// Test assigning into a symbolic offset.
406struct TestAssignIntoSymbolicOffset {
407 int **stuff[100];
408 void test(int x, int y);
409};
410
411void TestAssignIntoSymbolicOffset::test(int x, int y) {
412 x--;
413 if (x > 8 || x < 0)
414 return;
415 if (stuff[x])
416 return;
417 if (!stuff[x]) {
418 stuff[x] = new int*[y+1];
419 // Previously triggered a null dereference.
420 stuff[x][y] = 0; // no-warning
421 }
422}
423
Ted Kremenek5bd04952011-08-16 21:37:52 +0000424// Test loads from static fields. This previously triggered an uninitialized
425// value warning.
426class ClassWithStatic {
427public:
428 static const unsigned value = 1;
429};
430
431int rdar9948787_negative() {
432 ClassWithStatic classWithStatic;
433 unsigned value = classWithStatic.value;
434 if (value == 1)
435 return 1;
Jordan Rosed000b852013-10-03 16:57:03 +0000436 clang_analyzer_warnIfReached(); // no-warning
Ted Kremenek5bd04952011-08-16 21:37:52 +0000437 return 0;
438}
439
440int rdar9948787_positive() {
441 ClassWithStatic classWithStatic;
442 unsigned value = classWithStatic.value;
443 if (value == 0)
444 return 1;
Jordan Rosed000b852013-10-03 16:57:03 +0000445 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Ted Kremenek5bd04952011-08-16 21:37:52 +0000446 return 0;
447}
448
Ted Kremeneke4c66752011-09-30 03:51:54 +0000449// Regression test against global constants and switches.
450enum rdar10202899_ValT { rdar10202899_ValTA, rdar10202899_ValTB, rdar10202899_ValTC };
451const rdar10202899_ValT val = rdar10202899_ValTA;
452void rdar10202899_test1() {
453 switch (val) {
454 case rdar10202899_ValTA: {}
455 };
456}
457
458void rdar10202899_test2() {
459 if (val == rdar10202899_ValTA)
460 return;
Jordan Rosed000b852013-10-03 16:57:03 +0000461 clang_analyzer_warnIfReached(); // no-warning
Ted Kremeneke4c66752011-09-30 03:51:54 +0000462}
463
464void rdar10202899_test3() {
465 switch (val) {
466 case rdar10202899_ValTA: return;
467 default: ;
468 };
Jordan Rosed000b852013-10-03 16:57:03 +0000469 clang_analyzer_warnIfReached(); // no-warning
Ted Kremeneke4c66752011-09-30 03:51:54 +0000470}
471
Jim Goodnow IIe42a0ab2011-11-16 20:29:27 +0000472// This used to crash the analyzer because of the unnamed bitfield.
473void PR11249()
474{
475 struct {
476 char f1:4;
477 char :4;
478 char f2[1];
479 char f3;
480 } V = { 1, {2}, 3 };
Jim Goodnow IIe42a0ab2011-11-16 20:29:27 +0000481 if (V.f1 != 1)
Jordan Rosed000b852013-10-03 16:57:03 +0000482 clang_analyzer_warnIfReached(); // no-warning
Jim Goodnow IIe42a0ab2011-11-16 20:29:27 +0000483 if (V.f2[0] != 2)
Jordan Rosed000b852013-10-03 16:57:03 +0000484 clang_analyzer_warnIfReached(); // no-warning
Jim Goodnow IIe42a0ab2011-11-16 20:29:27 +0000485 if (V.f3 != 3)
Jordan Rosed000b852013-10-03 16:57:03 +0000486 clang_analyzer_warnIfReached(); // no-warning
Jim Goodnow IIe42a0ab2011-11-16 20:29:27 +0000487}
Ted Kremeneke4c66752011-09-30 03:51:54 +0000488
Ted Kremenek214323b2011-11-29 19:39:29 +0000489// Handle doing a load from the memory associated with the code for
490// a function.
491extern double nan( const char * );
492double PR11450() {
493 double NaN = *(double*) nan;
494 return NaN;
495}
496
Ted Kremenek60a44812011-12-01 07:39:23 +0000497// Test that 'this' is assumed non-null upon analyzing the entry to a "top-level"
Ted Kremeneka078ecf2011-12-01 05:29:42 +0000498// function (i.e., when not analyzing from a specific caller).
499struct TestNullThis {
500 int field;
501 void test();
502};
503
504void TestNullThis::test() {
505 int *p = &field;
506 if (p)
507 return;
508 field = 2; // no-warning
509}
510
Ted Kremenek337e4db2012-03-10 01:34:17 +0000511// Test handling of 'catch' exception variables, and not warning
512// about uninitialized values.
513enum MyEnum { MyEnumValue };
514MyEnum rdar10892489() {
515 try {
516 throw MyEnumValue;
517 } catch (MyEnum e) {
518 return e; // no-warning
519 }
520 return MyEnumValue;
521}
522
523MyEnum rdar10892489_positive() {
524 try {
525 throw MyEnumValue;
526 } catch (MyEnum e) {
527 int *p = 0;
Jordan Rosec32a4532012-08-18 00:30:23 +0000528 // FALSE NEGATIVE
529 *p = 0xDEADBEEF; // {{null}}
Ted Kremenek337e4db2012-03-10 01:34:17 +0000530 return e;
531 }
532 return MyEnumValue;
533}
534
Ted Kremenekce612f52012-03-16 05:58:15 +0000535// Test handling of catch with no condition variable.
536void PR11545() {
537 try
538 {
539 throw;
540 }
541 catch (...)
542 {
543 }
544}
545
546void PR11545_positive() {
547 try
548 {
549 throw;
550 }
551 catch (...)
552 {
553 int *p = 0;
Jordan Rosec32a4532012-08-18 00:30:23 +0000554 // FALSE NEGATIVE
555 *p = 0xDEADBEEF; // {{null}}
Ted Kremenekce612f52012-03-16 05:58:15 +0000556 }
557}
558
Ted Kremenek5aac0b62012-03-22 21:42:31 +0000559// Test handling taking the address of a field. While the analyzer
560// currently doesn't do anything intelligent here, this previously
561// resulted in a crash.
562class PR11146 {
563public:
564 struct Entry;
565 void baz();
566};
567
568struct PR11146::Entry {
569 int x;
570};
571
572void PR11146::baz() {
573 (void) &Entry::x;
574}
Ted Kremenekb98b9982012-04-05 05:56:31 +0000575
576// Test symbolicating a reference. In this example, the
577// analyzer (originally) didn't know how to handle x[index - index2],
578// returning an UnknownVal. The conjured symbol wasn't a location,
579// and would result in a crash.
580void rdar10924675(unsigned short x[], int index, int index2) {
581 unsigned short &y = x[index - index2];
582 if (y == 0)
583 return;
584}
Ted Kremenekc319c582012-05-08 05:13:40 +0000585
586// Test handling CXXScalarValueInitExprs.
587void rdar11401827() {
588 int x = int();
589 if (!x) {
Jordan Rosed000b852013-10-03 16:57:03 +0000590 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
Stephen Hines651f13c2014-04-23 16:59:28 -0700591 ; // Suppress warning that both branches are identical
Ted Kremenekc319c582012-05-08 05:13:40 +0000592 }
593 else {
Jordan Rosed000b852013-10-03 16:57:03 +0000594 clang_analyzer_warnIfReached(); // no-warning
Ted Kremenekc319c582012-05-08 05:13:40 +0000595 }
596}
597
Ted Kremenek10f77ad2012-06-22 23:55:50 +0000598//===---------------------------------------------------------------------===//
599// Handle inlining of C++ method calls.
600//===---------------------------------------------------------------------===//
601
602struct A {
603 int *p;
604 void foo(int *q) {
605 p = q;
606 }
607 void bar() {
608 *p = 0; // expected-warning {{null pointer}}
609 }
610};
611
612void test_inline() {
613 A a;
614 a.foo(0);
615 a.bar();
616}
617
Anna Zaksdac6cd52012-11-26 19:11:46 +0000618void test_alloca_in_a_recursive_function(int p1) {
619 __builtin_alloca (p1);
620 test_alloca_in_a_recursive_function(1);
621 test_alloca_in_a_recursive_function(2);
622}
Ted Kremenekbd8a11e2012-11-27 23:05:37 +0000623
624//===---------------------------------------------------------------------===//
625// Random tests.
626//===---------------------------------------------------------------------===//
627
628// Tests assigning using a C-style initializer to a struct
629// variable whose sub-field is also a struct. This currently
630// results in a CXXTempObjectRegion being created, but not
631// properly handled. For now, we just ignore that value
632// to avoid a crash (<rdar://problem/12753384>).
633struct RDar12753384_ClassA {
634 unsigned z;
635};
636struct RDar12753384_ClassB {
637 unsigned x;
638 RDar12753384_ClassA y[ 8 ] ;
639};
640unsigned RDar12753384() {
641 RDar12753384_ClassB w = { 0x00 };
642 RDar12753384_ClassA y[8];
643 return w.x;
644}
645
Ted Kremenek1994e392012-11-28 01:49:01 +0000646// This testcase tests whether we treat the anonymous union and union
647// the same way. This previously resulted in a "return of stack address"
648// warning because the anonymous union resulting in a temporary object
649// getting put into the initializer. We still aren't handling this correctly,
650// but now if a temporary object appears in an initializer we just ignore it.
651// Fixes <rdar://problem/12755044>.
652
653struct Rdar12755044_foo
654{
655 struct Rdar12755044_bar
656 {
657 union baz
658 {
659 int i;
660 };
661 } aBar;
662};
663
664struct Rdar12755044_foo_anon
665{
666 struct Rdar12755044_bar
667 {
668 union
669 {
670 int i;
671 };
672 } aBar;
673};
674
675const Rdar12755044_foo_anon *radar12755044_anon() {
676 static const Rdar12755044_foo_anon Rdar12755044_foo_list[] = { { { } } };
677 return Rdar12755044_foo_list; // no-warning
678}
679
680const Rdar12755044_foo *radar12755044() {
681 static const Rdar12755044_foo Rdar12755044_foo_list[] = { { { } } };
682 return Rdar12755044_foo_list; // no-warning
683}
Ted Kremenek9c046662012-11-29 00:50:20 +0000684
685// Test the correct handling of integer to bool conversions. Previously
686// this resulted in a false positive because integers were being truncated
687// and not tested for non-zero.
688void rdar12759044() {
689 int flag = 512;
690 if (!(flag & 512)) {
Jordan Rosed000b852013-10-03 16:57:03 +0000691 clang_analyzer_warnIfReached(); // no-warning
Ted Kremenek9c046662012-11-29 00:50:20 +0000692 }
693}
Ted Kremenekbeac9e32013-01-09 18:46:17 +0000694
695// The analyzer currently does not model complex types. Test that the load
696// from 'x' is not flagged as being uninitialized.
697typedef __complex__ float _ComplexT;
698void rdar12964481(_ComplexT *y) {
699 _ComplexT x;
700 __real__ x = 1.0;
701 __imag__ x = 1.0;
702 *y *= x; // no-warning
703}
704void rdar12964481_b(_ComplexT *y) {
705 _ComplexT x;
706 // Eventually this should be a warning.
707 *y *= x; // no-warning
708}
709
Ted Kremenek88de5a02013-03-22 21:30:22 +0000710// Test case for PR 12921. This previously produced
711// a bogus warning.
712static const int pr12921_arr[] = { 0, 1 };
713static const int pr12921_arrcount = sizeof(pr12921_arr)/sizeof(int);
714
715int pr12921(int argc, char **argv) {
716 int i, retval;
717 for (i = 0; i < pr12921_arrcount; i++) {
718 if (argc == i) {
719 retval = i;
720 break;
721 }
722 }
723
724 // No match
725 if (i == pr12921_arrcount) return 66;
726 return pr12921_arr[retval];
727}
728