xref: /llvm-project/clang/test/Analysis/array-struct.c (revision 23f0f4b7aee9d1f305d170370d85f42a8688af18)
1 // RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -verify %s
2 // RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -verify %s
3 // RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -verify %s
4 // RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -verify %s
5 
6 struct s {
7   int data;
8   int data_array[10];
9 };
10 
11 typedef struct {
12   int data;
13 } STYPE;
14 
15 void g(char *p);
16 void g1(struct s* p);
17 
18 // Array to pointer conversion. Array in the struct field.
19 void 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
34 void f2() {
35   char *p = "/usr/local";
36   char (*q)[4];
37   q = &"abc";
38 }
39 
40 // Typedef'ed struct definition.
41 void f3() {
42   STYPE s;
43 }
44 
45 // Initialize array with InitExprList.
46 void 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.
54 void f5() {
55   struct s data;
56   g1(&data);
57 }
58 
59 // AllocaRegion test.
60 void 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 
71 struct s2;
72 
73 void g2(struct s2 *p);
74 
75 // Incomplete struct pointer used as function argument.
76 void f7() {
77   struct s2 *p = __builtin_alloca(10);
78   g2(p);
79 }
80 
81 // sizeof() is unsigned while -1 is signed in array index.
82 void f8() {
83   int a[10];
84   a[sizeof(a)/sizeof(int) - 1] = 1; // no-warning
85 }
86 
87 // Initialization of struct array elements.
88 void f9() {
89   struct s a[10];
90 }
91 
92 // Initializing array with string literal.
93 void f10() {
94   char a1[4] = "abc";
95   char a3[6] = "abc";
96 }
97 
98 // Retrieve the default value of element/field region.
99 void 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.
108 void f12(int *list) {
109   unsigned i = 0;
110   list[i] = 1;
111 }
112 
113 struct 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.
121 void 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 
128 struct s3 {
129   int a[2];
130 };
131 
132 static struct s3 opt;
133 
134 // Test if the embedded array is retrieved correctly.
135 void f14() {
136   struct s3 my_opt = opt;
137 }
138 
139 void bar(int*);
140 
141 // Test if the array is correctly invalidated.
142 void f15() {
143   int a[10];
144   bar(a);
145   if (a[1]) // no-warning
146     (void)1;
147 }
148 
149 struct 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'.
155 void f16(struct s3 *p) {
156   struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
157 }
158 
159 void inv(struct s1 *);
160 
161 // Invalidate the struct field.
162 void f17() {
163   struct s1 t;
164   int x;
165   inv(&t);
166   if (t.e.d)
167     x = 1;
168 }
169 
170 void read(char*);
171 
172 void 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