1 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -Wno-pointer-to-int-cast -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare -analyzer-config eagerly-assume=false %s
4 void clang_analyzer_eval(int);
5 void clang_analyzer_dump(int);
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'.
23 void* memchr(const void *, int, __typeof__(sizeof(0)));
25 domain_port (const char *domain_b
, const char *domain_e
,
26 const char **domain_e_ptr
)
31 const char *colon
= memchr (domain_b
, ':', domain_e
- domain_b
);
33 for (p
= colon
+ 1; p
< domain_e
; p
++)
34 port
= 10 * port
+ (*p
- '0');
40 int d
= &y
- &x
; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result}}
45 d
= q
-p
; // no-warning
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}}
56 p
= &x
+ 1; // expected-warning{{Pointer arithmetic on non-array variables relies on memory layout, which is dangerous}}
59 p
= a
+ 1; // no-warning
62 // Allow arithmetic on different symbolic regions.
63 void f6(int *p
, int *q
) {
64 int d
= q
- p
; // no-warning
67 void null_operand(int *a
) {
69 // LHS is a label, RHS is NULL
70 clang_analyzer_eval(&&start
!= 0); // expected-warning{{TRUE}}
71 clang_analyzer_eval(&&start
>= 0); // expected-warning{{TRUE}}
72 clang_analyzer_eval(&&start
> 0); // expected-warning{{TRUE}}
73 clang_analyzer_eval((&&start
- 0) != 0); // expected-warning{{TRUE}}
75 // LHS is a non-symbolic value, RHS is NULL
76 clang_analyzer_eval(&a
!= 0); // expected-warning{{TRUE}}
77 clang_analyzer_eval(&a
>= 0); // expected-warning{{TRUE}}
78 clang_analyzer_eval(&a
> 0); // expected-warning{{TRUE}}
79 clang_analyzer_eval((&a
- 0) != 0); // expected-warning{{TRUE}}
81 // LHS is NULL, RHS is non-symbolic
82 // The same code is used for labels and non-symbolic values.
83 clang_analyzer_eval(0 != &a
); // expected-warning{{TRUE}}
84 clang_analyzer_eval(0 <= &a
); // expected-warning{{TRUE}}
85 clang_analyzer_eval(0 < &a
); // expected-warning{{TRUE}}
87 // LHS is a symbolic value, RHS is NULL
88 clang_analyzer_eval(a
!= 0); // expected-warning{{UNKNOWN}}
89 clang_analyzer_eval(a
>= 0); // expected-warning{{TRUE}}
90 clang_analyzer_eval(a
<= 0); // expected-warning{{UNKNOWN}}
91 clang_analyzer_eval((a
- 0) != 0); // expected-warning{{UNKNOWN}}
93 // LHS is NULL, RHS is a symbolic value
94 clang_analyzer_eval(0 != a
); // expected-warning{{UNKNOWN}}
95 clang_analyzer_eval(0 <= a
); // expected-warning{{TRUE}}
96 clang_analyzer_eval(0 < a
); // expected-warning{{UNKNOWN}}
99 void const_locs(void) {
100 char *a
= (char*)0x1000;
101 char *b
= (char*)0x1100;
103 clang_analyzer_eval(a
!= b
); // expected-warning{{TRUE}}
104 clang_analyzer_eval(a
< b
); // expected-warning{{TRUE}}
105 clang_analyzer_eval(a
<= b
); // expected-warning{{TRUE}}
106 clang_analyzer_eval((b
-a
) == 0x100); // expected-warning{{TRUE}}
108 clang_analyzer_eval(&&start
== a
); // expected-warning{{UNKNOWN}}
109 clang_analyzer_eval(a
== &&start
); // expected-warning{{UNKNOWN}}
110 clang_analyzer_eval(&a
== (char**)a
); // expected-warning{{UNKNOWN}}
111 clang_analyzer_eval((char**)a
== &a
); // expected-warning{{UNKNOWN}}
114 void array_matching_types(void) {
119 clang_analyzer_eval(a
!= b
); // expected-warning{{TRUE}}
120 clang_analyzer_eval(a
< b
); // expected-warning{{TRUE}}
121 clang_analyzer_eval(a
<= b
); // expected-warning{{TRUE}}
122 clang_analyzer_eval((b
-a
) != 0); // expected-warning{{TRUE}}
125 // This takes a different code path than array_matching_types()
126 void array_different_types(void) {
129 char *b
= (char*)&array
[5];
131 clang_analyzer_eval(a
!= b
); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
132 clang_analyzer_eval(a
< b
); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
133 clang_analyzer_eval(a
<= b
); // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
136 struct test
{ int x
; int y
; };
137 void struct_fields(void) {
140 clang_analyzer_eval(&a
.x
!= &a
.y
); // expected-warning{{TRUE}}
141 clang_analyzer_eval(&a
.x
< &a
.y
); // expected-warning{{TRUE}}
142 clang_analyzer_eval(&a
.x
<= &a
.y
); // expected-warning{{TRUE}}
144 clang_analyzer_eval(&a
.x
!= &b
.x
); // expected-warning{{TRUE}}
145 clang_analyzer_eval(&a
.x
> &b
.x
); // expected-warning{{UNKNOWN}}
146 clang_analyzer_eval(&a
.x
>= &b
.x
); // expected-warning{{UNKNOWN}}
149 void mixed_region_types(void) {
152 void *a
= &array
, *b
= &s
;
154 clang_analyzer_eval(&a
!= &b
); // expected-warning{{TRUE}}
155 clang_analyzer_eval(&a
> &b
); // expected-warning{{UNKNOWN}}
156 clang_analyzer_eval(&a
>= &b
); // expected-warning{{UNKNOWN}}
159 void symbolic_region(int *p
) {
162 clang_analyzer_eval(&a
!= p
); // expected-warning{{TRUE}}
163 clang_analyzer_eval(&a
> p
); // expected-warning{{UNKNOWN}}
164 clang_analyzer_eval(&a
>= p
); // expected-warning{{UNKNOWN}}
167 void PR7527 (int *p
) {
168 if (((int) p
) & 1) // not crash
172 void use_symbols(int *lhs
, int *rhs
) {
173 clang_analyzer_eval(lhs
< rhs
); // expected-warning{{UNKNOWN}}
176 clang_analyzer_eval(lhs
< rhs
); // expected-warning{{FALSE}}
178 clang_analyzer_eval(lhs
- rhs
); // expected-warning{{UNKNOWN}}
179 if ((lhs
- rhs
) != 5)
181 clang_analyzer_eval((lhs
- rhs
) == 5); // expected-warning{{TRUE}}
184 void equal_implies_zero(int *lhs
, int *rhs
) {
185 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{UNKNOWN}}
187 clang_analyzer_eval(lhs
!= rhs
); // expected-warning{{FALSE}}
188 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{TRUE}}
191 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
192 clang_analyzer_eval(lhs
!= rhs
); // expected-warning{{TRUE}}
193 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{FALSE}}
196 void zero_implies_equal(int *lhs
, int *rhs
) {
197 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{UNKNOWN}}
198 if ((rhs
- lhs
) == 0) {
199 clang_analyzer_eval(lhs
!= rhs
); // expected-warning{{FALSE}}
200 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{TRUE}}
203 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{FALSE}}
204 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
205 clang_analyzer_eval(lhs
!= rhs
); // expected-warning{{TRUE}}
208 void comparisons_imply_size(int *lhs
, int *rhs
) {
209 clang_analyzer_eval(lhs
<= rhs
); // expected-warning{{UNKNOWN}}
212 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{FALSE}}
216 clang_analyzer_eval(lhs
<= rhs
); // expected-warning{{TRUE}}
217 // FIXME: In Z3ConstraintManager, ptrdiff_t is mapped to signed bitvector. However, this does not directly imply the unsigned comparison.
218 #ifdef ANALYZER_CM_Z3
219 clang_analyzer_eval((rhs
- lhs
) >= 0); // expected-warning{{UNKNOWN}}
221 clang_analyzer_eval((rhs
- lhs
) >= 0); // expected-warning{{TRUE}}
223 clang_analyzer_eval((rhs
- lhs
) > 0); // expected-warning{{UNKNOWN}}
226 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{TRUE}}
230 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
231 clang_analyzer_eval(lhs
< rhs
); // expected-warning{{TRUE}}
232 #ifdef ANALYZER_CM_Z3
233 clang_analyzer_eval((rhs
- lhs
) > 0); // expected-warning{{UNKNOWN}}
235 clang_analyzer_eval((rhs
- lhs
) > 0); // expected-warning{{TRUE}}
239 void size_implies_comparison(int *lhs
, int *rhs
) {
240 clang_analyzer_eval(lhs
<= rhs
); // expected-warning{{UNKNOWN}}
242 if ((rhs
- lhs
) < 0) {
243 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
247 #ifdef ANALYZER_CM_Z3
248 clang_analyzer_eval(lhs
<= rhs
); // expected-warning{{UNKNOWN}}
250 clang_analyzer_eval(lhs
<= rhs
); // expected-warning{{TRUE}}
252 clang_analyzer_eval((rhs
- lhs
) >= 0); // expected-warning{{TRUE}}
253 clang_analyzer_eval((rhs
- lhs
) > 0); // expected-warning{{UNKNOWN}}
255 if ((rhs
- lhs
) <= 0) {
256 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{TRUE}}
260 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
261 #ifdef ANALYZER_CM_Z3
262 clang_analyzer_eval(lhs
< rhs
); // expected-warning{{UNKNOWN}}
264 clang_analyzer_eval(lhs
< rhs
); // expected-warning{{TRUE}}
266 clang_analyzer_eval((rhs
- lhs
) > 0); // expected-warning{{TRUE}}
269 void zero_implies_reversed_equal(int *lhs
, int *rhs
) {
270 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{UNKNOWN}}
271 if ((rhs
- lhs
) == 0) {
272 clang_analyzer_eval(rhs
!= lhs
); // expected-warning{{FALSE}}
273 clang_analyzer_eval(rhs
== lhs
); // expected-warning{{TRUE}}
276 clang_analyzer_eval((rhs
- lhs
) == 0); // expected-warning{{FALSE}}
277 clang_analyzer_eval(rhs
== lhs
); // expected-warning{{FALSE}}
278 clang_analyzer_eval(rhs
!= lhs
); // expected-warning{{TRUE}}
281 void canonical_equal(int *lhs
, int *rhs
) {
282 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{UNKNOWN}}
284 clang_analyzer_eval(rhs
== lhs
); // expected-warning{{TRUE}}
287 clang_analyzer_eval(lhs
== rhs
); // expected-warning{{FALSE}}
288 clang_analyzer_eval(rhs
== lhs
); // expected-warning{{FALSE}}
291 void compare_element_region_and_base(int *p
) {
293 clang_analyzer_eval(p
== q
); // expected-warning{{FALSE}}
300 void symbolicFieldRegion(struct Point
*points
, int i
, int j
) {
301 clang_analyzer_eval(&points
[i
].x
== &points
[j
].x
);// expected-warning{{UNKNOWN}}
302 clang_analyzer_eval(&points
[i
].x
== &points
[i
].y
);// expected-warning{{FALSE}}
303 clang_analyzer_eval(&points
[i
].x
< &points
[i
].y
);// expected-warning{{TRUE}}
306 void negativeIndex(char *str
) {
308 clang_analyzer_eval(*(str
+ 1) == 'a'); // expected-warning{{TRUE}}
309 clang_analyzer_eval(*(str
- 1) == 'a'); // expected-warning{{UNKNOWN}}
311 char *ptr1
= str
- 1;
312 clang_analyzer_eval(*ptr1
== 'a'); // expected-warning{{UNKNOWN}}
316 clang_analyzer_eval(*ptr2
== 'a'); // expected-warning{{UNKNOWN}}
320 clang_analyzer_eval(*ptr3
== 'a'); // expected-warning{{UNKNOWN}}
323 void test_no_crash_on_pointer_to_label(void) {
329 typedef __attribute__((__ext_vector_type__(2))) float simd_float2
;
330 float test_nowarning_on_vector_deref(void) {
331 simd_float2 x
= {0, 1};
332 return x
[1]; // no-warning
339 // These three expressions should produce the same sym vals.
340 void struct_pointer_canon(struct s
*ps
) {
342 clang_analyzer_dump((*ps
).v
);
343 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}
344 clang_analyzer_dump(ps
[0].v
);
345 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}
346 clang_analyzer_dump(ps
->v
);
347 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<struct s * ps>},0 S64b,struct s}.v>}}
348 clang_analyzer_eval((*ps
).v
== ps
[0].v
); // expected-warning{{TRUE}}
349 clang_analyzer_eval((*ps
).v
== ps
->v
); // expected-warning{{TRUE}}
350 clang_analyzer_eval(ps
[0].v
== ps
->v
); // expected-warning{{TRUE}}
353 void struct_pointer_canon_bidim(struct s
**ps
) {
355 clang_analyzer_eval(&(ps
[0][0].v
) == &((*ps
)->v
)); // expected-warning{{TRUE}}
360 void struct_pointer_canon_typedef(T1
*ps
) {
362 clang_analyzer_dump((*ps
).v
);
363 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}
364 clang_analyzer_dump(ps
[0].v
);
365 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}
366 clang_analyzer_dump(ps
->v
);
367 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<T1 * ps>},0 S64b,struct s}.v>}}
368 clang_analyzer_eval((*ps
).v
== ps
[0].v
); // expected-warning{{TRUE}}
369 clang_analyzer_eval((*ps
).v
== ps
->v
); // expected-warning{{TRUE}}
370 clang_analyzer_eval(ps
[0].v
== ps
->v
); // expected-warning{{TRUE}}
373 void struct_pointer_canon_bidim_typedef(T1
**ps
) {
375 clang_analyzer_eval(&(ps
[0][0].v
) == &((*ps
)->v
)); // expected-warning{{TRUE}}
378 void struct_pointer_canon_const(const struct s
*ps
) {
380 clang_analyzer_dump((*ps
).v
);
381 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}
382 clang_analyzer_dump(ps
[0].v
);
383 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}
384 clang_analyzer_dump(ps
->v
);
385 // expected-warning-re@-1{{reg_${{[[:digit:]]+}}<int Element{SymRegion{reg_${{[[:digit:]]+}}<const struct s * ps>},0 S64b,struct s}.v>}}
386 clang_analyzer_eval((*ps
).v
== ps
[0].v
); // expected-warning{{TRUE}}
387 clang_analyzer_eval((*ps
).v
== ps
->v
); // expected-warning{{TRUE}}
388 clang_analyzer_eval(ps
[0].v
== ps
->v
); // expected-warning{{TRUE}}