1 | // RUN: %clang_analyze_cc1 -w -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -verify %s |
2 | |
3 | void clang_analyzer_eval(int); |
4 | |
5 | struct S { |
6 | int x, y; |
7 | int z[2]; |
8 | }; |
9 | |
10 | void testOffsets(struct S *s, int coin) { |
11 | if (s != 0) |
12 | return; |
13 | |
14 | // FIXME: Here we are testing the hack that computes offsets to null pointers |
15 | // as 0 in order to find null dereferences of not-exactly-null pointers, |
16 | // such as &(s->y) below, which is equal to 4 rather than 0 in run-time. |
17 | |
18 | // These are indeed null. |
19 | clang_analyzer_eval(s == 0); // expected-warning{{TRUE}} |
20 | clang_analyzer_eval(&(s->x) == 0); // expected-warning{{TRUE}} |
21 | |
22 | // FIXME: These should ideally be true. |
23 | clang_analyzer_eval(&(s->y) == 4); // expected-warning{{FALSE}} |
24 | clang_analyzer_eval(&(s->z[0]) == 8); // expected-warning{{FALSE}} |
25 | clang_analyzer_eval(&(s->z[1]) == 12); // expected-warning{{FALSE}} |
26 | |
27 | // FIXME: These should ideally be false. |
28 | clang_analyzer_eval(&(s->y) == 0); // expected-warning{{TRUE}} |
29 | clang_analyzer_eval(&(s->z[0]) == 0); // expected-warning{{TRUE}} |
30 | clang_analyzer_eval(&(s->z[1]) == 0); // expected-warning{{TRUE}} |
31 | |
32 | // But these should still be reported as null dereferences. |
33 | if (coin) |
34 | s->y = 5; // expected-warning{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 's')}} |
35 | else |
36 | s->z[1] = 6; // expected-warning{{Array access (via field 'z') results in a null pointer dereference}} |
37 | } |
38 | |