1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify 2 3 void clang_analyzer_eval(int); 4 5 unsigned foo(); 6 typedef struct bf { unsigned x:2; } bf; bar()7void bar() { 8 bf y; 9 *(unsigned*)&y = foo(); 10 y.x = 1; 11 } 12 13 struct s { 14 int n; 15 }; 16 f()17void f() { 18 struct s a; 19 int *p = &(a.n) + 1; 20 } 21 22 typedef struct { 23 int x,y; 24 } Point; 25 26 Point getit(void); test()27void test() { 28 Point p; 29 (void)(p = getit()).x; 30 } 31 32 #define true ((bool)1) 33 #define false ((bool)0) 34 typedef _Bool bool; 35 36 testLazyCompoundVal()37void testLazyCompoundVal() { 38 Point p = {42, 0}; 39 Point q; 40 clang_analyzer_eval((q = p).x == 42); // expected-warning{{TRUE}} 41 clang_analyzer_eval(q.x == 42); // expected-warning{{TRUE}} 42 } 43 44 45 struct Bits { 46 unsigned a : 1; 47 unsigned b : 2; 48 unsigned c : 1; 49 50 bool x; 51 52 struct InnerBits { 53 bool y; 54 55 unsigned d : 16; 56 unsigned e : 6; 57 unsigned f : 2; 58 } inner; 59 }; 60 testBitfields()61void testBitfields() { 62 struct Bits bits; 63 64 if (foo() && bits.b) // expected-warning {{garbage}} 65 return; 66 if (foo() && bits.inner.e) // expected-warning {{garbage}} 67 return; 68 69 bits.c = 1; 70 clang_analyzer_eval(bits.c == 1); // expected-warning {{TRUE}} 71 72 if (foo() && bits.b) // expected-warning {{garbage}} 73 return; 74 if (foo() && bits.x) // expected-warning {{garbage}} 75 return; 76 77 bits.x = true; 78 clang_analyzer_eval(bits.x == true); // expected-warning{{TRUE}} 79 bits.b = 2; 80 clang_analyzer_eval(bits.x == true); // expected-warning{{TRUE}} 81 if (foo() && bits.c) // no-warning 82 return; 83 84 bits.inner.e = 50; 85 if (foo() && bits.inner.e) // no-warning 86 return; 87 if (foo() && bits.inner.y) // expected-warning {{garbage}} 88 return; 89 if (foo() && bits.inner.f) // expected-warning {{garbage}} 90 return; 91 92 extern struct InnerBits getInner(); 93 bits.inner = getInner(); 94 95 if (foo() && bits.inner.e) // no-warning 96 return; 97 if (foo() && bits.inner.y) // no-warning 98 return; 99 if (foo() && bits.inner.f) // no-warning 100 return; 101 102 bits.inner.f = 1; 103 104 if (foo() && bits.inner.e) // no-warning 105 return; 106 if (foo() && bits.inner.y) // no-warning 107 return; 108 if (foo() && bits.inner.f) // no-warning 109 return; 110 111 if (foo() && bits.a) // expected-warning {{garbage}} 112 return; 113 } 114 115 116 //----------------------------------------------------------------------------- 117 // Incorrect behavior 118 //----------------------------------------------------------------------------- 119 testTruncation()120void testTruncation() { 121 struct Bits bits; 122 bits.c = 0x11; // expected-warning{{implicit truncation}} 123 // FIXME: We don't model truncation of bitfields. 124 clang_analyzer_eval(bits.c == 1); // expected-warning {{FALSE}} 125 } 126