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