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()7 void bar() {
8   bf y;
9   *(unsigned*)&y = foo();
10   y.x = 1;
11 }
12 
13 struct s {
14   int n;
15 };
16 
f()17 void 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()27 void 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()37 void 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()61 void 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()120 void 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