fields.c revision d764e20189dbb42b38ada383a0a159f6adc0d56c
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
2
3void clang_analyzer_eval(int);
4
5unsigned foo();
6typedef struct bf { unsigned x:2; } bf;
7void bar() {
8  bf y;
9  *(unsigned*)&y = foo();
10  y.x = 1;
11}
12
13struct s {
14  int n;
15};
16
17void f() {
18  struct s a;
19  int *p = &(a.n) + 1;
20}
21
22typedef struct {
23  int x,y;
24} Point;
25
26Point getit(void);
27void test() {
28  Point p;
29  (void)(p = getit()).x;
30}
31
32#define true ((bool)1)
33#define false ((bool)0)
34typedef _Bool bool;
35
36
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
45struct 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
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
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