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