Clang Project

clang_source_code/test/Analysis/inlining/inline-defensive-checks.c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
2
3// Perform inline defensive checks.
4void idc(void *p) {
5 if (p)
6 ;
7}
8
9int test01(int *p) {
10  if (p)
11    ;
12  return *p; // expected-warning {{Dereference of null pointer}}
13}
14
15int test02(int *p, int *x) {
16  if (p)
17    ;
18  idc(p);
19 if (x)
20 ;
21  return *p; // expected-warning {{Dereference of null pointer}}
22}
23
24int test03(int *p, int *x) {
25 idc(p);
26 if (p)
27 ;
28 return *p; // False negative
29}
30
31int deref04(int *p) {
32  return *p; // expected-warning {{Dereference of null pointer}}
33}
34
35int test04(int *p) {
36  if (p)
37    ;
38  idc(p);
39  return deref04(p);
40}
41
42int test11(int *q, int *x) {
43 int *p = q;
44 if (q)
45 ;
46 if (x)
47 ;
48 return *p; // expected-warning{{Dereference of null pointer}}
49}
50
51int test12(int *q) {
52 int *p = q;
53 idc(q);
54 return *p;
55}
56
57int test13(int *q) {
58 int *p = q;
59 idc(p);
60 return *p;
61}
62
63int test21(int *q, int *x) {
64 if (q)
65 ;
66 if (x)
67 ;
68 int *p = q;
69 return *p; // expected-warning{{Dereference of null pointer}}
70}
71
72int test22(int *q, int *x) {
73  idc(q);
74 if (x)
75 ;
76 int *p = q;
77 return *p;
78}
79
80int test23(int *q, int *x) {
81  idc(q);
82 if (x)
83 ;
84 int *p = q;
85  if (!p)
86    ;
87 return *p; // False negative
88}
89
90void use(char *p) {
91  if (!p)
92    return;
93  p[0] = 'a';
94}
95
96void test24(char *buffer) {
97  use(buffer);
98  buffer[1] = 'b';
99}
100
101// Ensure idc works on pointers with constant offset.
102void idcchar(const char *s2) {
103  if(s2)
104    ;
105}
106void testConstantOffset(char *value) {
107  char *cursor = value + 5;
108  idcchar(cursor);
109  if (*cursor) {
110    cursor++;
111  }
112}
113
114// Ensure idc works for integer zero values (ex: suppressed div by zero).
115void idcZero(int assume) {
116  if (assume)
117    ;
118}
119
120int idcTriggerZeroValue(int m) {
121  idcZero(m);
122  return 5/m; // no-warning
123}
124
125int idcTriggerZeroValueThroughCall(int i) {
126  return 5/i; // no-warning
127}
128void idcTrackZeroValueThroughCall(int x) {
129  idcZero(x);
130  idcTriggerZeroValueThroughCall(x);
131}
132
133int idcTriggerZeroThroughDoubleAssignemnt(int i) {
134  return 5/i; // no-warning
135}
136void idcTrackZeroThroughDoubleAssignemnt(int x) {
137  idcZero(x);
138  int y = x;
139  int z = y;
140  idcTriggerZeroValueThroughCall(z);
141}
142
143struct S {
144  int f1;
145  int f2;
146};
147
148void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
149  idc(s);
150  *(&(s->f1)) = 7; // no-warning
151}
152
153void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
154  idc(s);
155  int *x = &(s->f2);
156  *x = 7; // no-warning
157}
158
159void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
160  idc(s);
161  int *x = &(s->f2) - 1;
162  *x = 7; // no-warning
163}
164
165void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
166  idc(s);
167  int *x = &(s->f1);
168  *x = 7; // no-warning
169}
170
171void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
172  idc(s);
173  int *x = &*&(s->f1);
174  *x = 7; // no-warning
175}
176
177void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
178  idc(s);
179  int *x = &*&((++s)->f1);
180  *x = 7; // no-warning
181}
182
183
184struct S2 {
185  int a[1];
186};
187
188void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
189  idc(s);
190  *(&(s->a[0])) = 7; // no-warning
191}
192
193void idcTrackConstraintThroughSymbolicRegion(int **x) {
194  idc(*x);
195  // FIXME: Should not warn.
196  **x = 7; // expected-warning{{Dereference of null pointer}}
197}
198
199void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {
200  idc(*x);
201  // FIXME: Should not warn.
202  *(*x) = 7; // expected-warning{{Dereference of null pointer}}
203}
204
205int *idcPlainNull(int coin) {
206  if (coin)
207    return 0;
208  static int X;
209  return &X;
210}
211
212void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
213  *x = idcPlainNull(coin);
214  **x = 7; // no-warning
215}
216
217void idcTrackZeroValueThroughSymbolicRegionAndParens(int coin, int **x) {
218  *x = idcPlainNull(coin);
219  *(*x) = 7; // no-warning
220}
221
222struct WithInt {
223  int i;
224};
225
226struct WithArray {
227  struct WithInt arr[1];
228};
229
230struct WithArray *idcPlainNullWithArray(int coin) {
231  if (coin)
232    return 0;
233  static struct WithArray S;
234  return &S;
235}
236
237void idcTrackZeroValueThroughSymbolicRegionWithArray(int coin, struct WithArray **s) {
238  *s = idcPlainNullWithArray(coin);
239  (*s)->arr[0].i = 1; // no-warning
240  // Same thing.
241  (*s)->arr->i = 1; // no-warning
242}
243