ptr-arith.c revision 38c8fe705ec4a8efa8992b99ab6d264fff14ca36
1// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr,core.experimental.PointerArithm,core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
2// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr,core.experimental.PointerArithm,core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple i686-apple-darwin9 %s
3
4// Used to trigger warnings for unreachable paths.
5#define WARN do { int a, b; int c = &b-&a; } while (0)
6
7void f1() {
8  int a[10];
9  int *p = a;
10  ++p;
11}
12
13char* foo();
14
15void f2() {
16  char *p = foo();
17  ++p;
18}
19
20// This test case checks if we get the right rvalue type of a TypedViewRegion.
21// The ElementRegion's type depends on the array region's rvalue type. If it was
22// a pointer type, we would get a loc::SymbolVal for '*p'.
23void* memchr();
24static int
25domain_port (const char *domain_b, const char *domain_e,
26             const char **domain_e_ptr)
27{
28  int port = 0;
29
30  const char *p;
31  const char *colon = memchr (domain_b, ':', domain_e - domain_b);
32
33  for (p = colon + 1; p < domain_e ; p++)
34    port = 10 * port + (*p - '0');
35  return port;
36}
37
38void f3() {
39  int x, y;
40  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
41
42  int a[10];
43  int *p = &a[2];
44  int *q = &a[8];
45  d = q-p; // no-warning
46}
47
48void f4() {
49  int *p;
50  p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
51}
52
53void f5() {
54  int x, y;
55  int *p;
56  p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
57
58  int a[10];
59  p = a + 1; // no-warning
60}
61
62// Allow arithmetic on different symbolic regions.
63void f6(int *p, int *q) {
64  int d = q - p; // no-warning
65}
66
67void null_operand(int *a) {
68start:
69  // LHS is a label, RHS is NULL
70  if (&&start == 0)
71    WARN; // no-warning
72  if (&&start <  0)
73    WARN; // no-warning
74  if (&&start <= 0)
75    WARN; // no-warning
76  if (!(&&start != 0))
77    WARN; // no-warning
78  if (!(&&start >  0))
79    WARN; // no-warning
80  if (!(&&start >= 0))
81    WARN; // no-warning
82  if (!(&&start - 0))
83    WARN; // no-warning
84
85  // LHS is a non-symbolic value, RHS is NULL
86  if (&a == 0)
87    WARN; // no-warning
88  if (&a <  0)
89    WARN; // no-warning
90  if (&a <= 0)
91    WARN; // no-warning
92  if (!(&a != 0))
93    WARN; // no-warning
94  if (!(&a >  0))
95    WARN; // no-warning
96  if (!(&a >= 0))
97    WARN; // no-warning
98
99  if (!(&a - 0)) // expected-warning{{Pointer arithmetic done on non-array variables}}
100    WARN; // no-warning
101
102  // LHS is NULL, RHS is non-symbolic
103  // The same code is used for labels and non-symbolic values.
104  if (0 == &a)
105    WARN; // no-warning
106  if (0 >  &a)
107    WARN; // no-warning
108  if (0 >= &a)
109    WARN; // no-warning
110  if (!(0 != &a))
111    WARN; // no-warning
112  if (!(0 <  &a))
113    WARN; // no-warning
114  if (!(0 <= &a))
115    WARN; // no-warning
116
117  // LHS is a symbolic value, RHS is NULL
118  if (a == 0)
119    WARN; // expected-warning{{}}
120  if (a <  0)
121    WARN; // no-warning
122  if (a <= 0)
123    WARN; // expected-warning{{}}
124  if (!(a != 0))
125    WARN; // expected-warning{{}}
126  if (!(a >  0))
127    WARN; // expected-warning{{}}
128  if (!(a >= 0))
129    WARN; // no-warning
130  if (!(a - 0))
131    WARN; // expected-warning{{}}
132
133  // LHS is NULL, RHS is a symbolic value
134  if (0 == a)
135    WARN; // expected-warning{{}}
136  if (0 >  a)
137    WARN; // no-warning
138  if (0 >= a)
139    WARN; // expected-warning{{}}
140  if (!(0 != a))
141    WARN; // expected-warning{{}}
142  if (!(0 <  a))
143    WARN; // expected-warning{{}}
144  if (!(0 <= a))
145    WARN; // no-warning
146}
147
148void const_locs() {
149  char *a = (char*)0x1000;
150  char *b = (char*)0x1100;
151start:
152  if (a==b)
153    WARN; // no-warning
154  if (!(a!=b))
155    WARN; // no-warning
156  if (a>b)
157    WARN; // no-warning
158  if (b<a)
159    WARN; // no-warning
160  if (a>=b)
161    WARN; // no-warning
162  if (b<=a)
163    WARN; // no-warning
164  if (b-a != 0x100)
165    WARN; // no-warning
166
167  if (&&start == a)
168    WARN; // expected-warning{{}}
169  if (a == &&start)
170    WARN; // expected-warning{{}}
171  if (&a == (char**)a)
172    WARN; // expected-warning{{}}
173  if ((char**)a == &a)
174    WARN; // expected-warning{{}}
175}
176
177void array_matching_types() {
178  int array[10];
179  int *a = &array[2];
180  int *b = &array[5];
181
182  if (a==b)
183    WARN; // no-warning
184  if (!(a!=b))
185    WARN; // no-warning
186  if (a>b)
187    WARN; // no-warning
188  if (b<a)
189    WARN; // no-warning
190  if (a>=b)
191    WARN; // no-warning
192  if (b<=a)
193    WARN; // no-warning
194  if ((b-a) == 0)
195    WARN; // no-warning
196}
197
198// This takes a different code path than array_matching_types()
199void array_different_types() {
200  int array[10];
201  int *a = &array[2];
202  char *b = (char*)&array[5];
203
204  if (a==b) // expected-warning{{comparison of distinct pointer types}}
205    WARN; // no-warning
206  if (!(a!=b)) // expected-warning{{comparison of distinct pointer types}}
207    WARN; // no-warning
208  if (a>b) // expected-warning{{comparison of distinct pointer types}}
209    WARN; // no-warning
210  if (b<a) // expected-warning{{comparison of distinct pointer types}}
211    WARN; // no-warning
212  if (a>=b) // expected-warning{{comparison of distinct pointer types}}
213    WARN; // no-warning
214  if (b<=a) // expected-warning{{comparison of distinct pointer types}}
215    WARN; // no-warning
216}
217
218struct test { int x; int y; };
219void struct_fields() {
220  struct test a, b;
221
222  if (&a.x == &a.y)
223    WARN; // no-warning
224  if (!(&a.x != &a.y))
225    WARN; // no-warning
226  if (&a.x > &a.y)
227    WARN; // no-warning
228  if (&a.y < &a.x)
229    WARN; // no-warning
230  if (&a.x >= &a.y)
231    WARN; // no-warning
232  if (&a.y <= &a.x)
233    WARN; // no-warning
234
235  if (&a.x == &b.x)
236    WARN; // no-warning
237  if (!(&a.x != &b.x))
238    WARN; // no-warning
239  if (&a.x > &b.x)
240    WARN; // expected-warning{{}}
241  if (&b.x < &a.x)
242    WARN; // expected-warning{{}}
243  if (&a.x >= &b.x)
244    WARN; // expected-warning{{}}
245  if (&b.x <= &a.x)
246    WARN; // expected-warning{{}}
247}
248
249void mixed_region_types() {
250  struct test s;
251  int array[2];
252  void *a = &array, *b = &s;
253
254  if (&a == &b)
255    WARN; // no-warning
256  if (!(&a != &b))
257    WARN; // no-warning
258  if (&a > &b)
259    WARN; // expected-warning{{}}
260  if (&b < &a)
261    WARN; // expected-warning{{}}
262  if (&a >= &b)
263    WARN; // expected-warning{{}}
264  if (&b <= &a)
265    WARN; // expected-warning{{}}
266}
267
268void symbolic_region(int *p) {
269  int a;
270
271  if (&a == p)
272    WARN; // expected-warning{{}}
273  if (&a != p)
274    WARN; // expected-warning{{}}
275  if (&a > p)
276    WARN; // expected-warning{{}}
277  if (&a < p)
278    WARN; // expected-warning{{}}
279  if (&a >= p)
280    WARN; // expected-warning{{}}
281  if (&a <= p)
282    WARN; // expected-warning{{}}
283}
284
285void PR7527 (int *p) {
286  if (((int) p) & 1) // not crash
287    return;
288}
289