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