array-struct.c revision 4fcfde4d5c8f25e40720972a5543d538a0dcb220
1// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=basic -verify %s
2// RUN: clang-cc -analyze -checker-cfref -analyzer-store=basic -analyzer-constraints=range -verify %s
3// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=basic -verify %s
4// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
5
6struct s {
7  int data;
8  int data_array[10];
9};
10
11typedef struct {
12  int data;
13} STYPE;
14
15void g(char *p);
16void g1(struct s* p);
17
18// Array to pointer conversion. Array in the struct field.
19void f(void) {
20  int a[10];
21  int (*p)[10];
22  p = &a;
23  (*p)[3] = 1;
24
25  struct s d;
26  struct s *q;
27  q = &d;
28  q->data = 3;
29  d.data_array[9] = 17;
30}
31
32// StringLiteral in lvalue context and pointer to array type.
33// p: ElementRegion, q: StringRegion
34void f2() {
35  char *p = "/usr/local";
36  char (*q)[4];
37  q = &"abc";
38}
39
40// Typedef'ed struct definition.
41void f3() {
42  STYPE s;
43}
44
45// Initialize array with InitExprList.
46void f4() {
47  int a[] = { 1, 2, 3};
48  int b[3] = { 1, 2 };
49  struct s c[] = {{1,{1}}};
50}
51
52// Struct variable in lvalue context.
53// Assign UnknownVal to the whole struct.
54void f5() {
55  struct s data;
56  g1(&data);
57}
58
59// AllocaRegion test.
60void f6() {
61  char *p;
62  p = __builtin_alloca(10);
63  g(p);
64  char c = *p;
65  p[1] = 'a';
66  // Test if RegionStore::EvalBinOp converts the alloca region to element
67  // region.
68  p += 2;
69}
70
71struct s2;
72
73void g2(struct s2 *p);
74
75// Incomplete struct pointer used as function argument.
76void f7() {
77  struct s2 *p = __builtin_alloca(10);
78  g2(p);
79}
80
81// sizeof() is unsigned while -1 is signed in array index.
82void f8() {
83  int a[10];
84  a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
85}
86
87// Initialization of struct array elements.
88void f9() {
89  struct s a[10];
90}
91
92// Initializing array with string literal.
93void f10() {
94  char a1[4] = "abc";
95  char a3[6] = "abc";
96}
97
98// Retrieve the default value of element/field region.
99void f11() {
100  struct s a;
101  g1(&a);
102  if (a.data == 0) // no-warning
103    a.data = 1;
104}
105
106// Convert unsigned offset to signed when creating ElementRegion from
107// SymbolicRegion.
108void f12(int *list) {
109  unsigned i = 0;
110  list[i] = 1;
111}
112
113struct s1 {
114  struct s2 {
115    int d;
116  } e;
117};
118
119// The binding of a.e.d should not be removed. Test recursive subregion map
120// building: a->e, e->d. Only then 'a' could be added to live region roots.
121void f13(double timeout) {
122  struct s1 a;
123  a.e.d = (int) timeout;
124  if (a.e.d == 10)
125    a.e.d = 4;
126}
127
128struct s3 {
129  int a[2];
130};
131
132static struct s3 opt;
133
134// Test if the embedded array is retrieved correctly.
135void f14() {
136  struct s3 my_opt = opt;
137}
138
139void bar(int*);
140
141// Test if the array is correctly invalidated.
142void f15() {
143  int a[10];
144  bar(a);
145  if (a[1]) // no-warning
146    (void)1;
147}
148
149struct s3 p[1];
150
151// Code from postgresql.
152// Current cast logic of region store mistakenly leaves the final result region
153// an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
154// assigns to 'a'.
155void f16(struct s3 *p) {
156  struct s3 a = *((struct s3*) ((char*) &p[0]));
157}
158
159void inv(struct s1 *);
160
161// Invalidate the struct field.
162void f17() {
163  struct s1 t;
164  int x;
165  inv(&t);
166  if (t.e.d)
167    x = 1;
168}
169
170void read(char*);
171
172void f18() {
173  char *q;
174  char *p = (char *) __builtin_alloca(10);
175  read(p);
176  q = p;
177  q++;
178  if (*q) { // no-warning
179  }
180}
181