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