blob: a07138e50d7a10beabea54abc9795aee0eb52cef [file] [log] [blame]
Tom Caredf4ca422010-07-16 20:41:41 +00001// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
Ted Kremenekebd42f42010-03-18 01:22:39 +00002// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
3// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
4// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
5// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
Ted Kremenek8aefcbf2007-11-19 06:38:23 +00006
Ted Kremenek49a2fd22008-04-14 15:56:17 +00007void f1() {
Ted Kremenekebd42f42010-03-18 01:22:39 +00008 int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
Ted Kremenek0fdf06e2008-03-19 07:31:52 +00009 int abc=1;
Ted Kremenekebd42f42010-03-18 01:22:39 +000010 long idx=abc+3*5; // expected-warning {{never read}} expected-warning{{unused variable 'idx'}}
Ted Kremenekaa395ba2007-11-18 20:06:35 +000011}
Ted Kremenek8aefcbf2007-11-19 06:38:23 +000012
Ted Kremenek49a2fd22008-04-14 15:56:17 +000013void f2(void *b) {
Ted Kremenek8aefcbf2007-11-19 06:38:23 +000014 char *c = (char*)b; // no-warning
Ted Kremenekebd42f42010-03-18 01:22:39 +000015 char *d = b+1; // expected-warning {{never read}} expected-warning{{unused variable 'd'}}
Chris Lattner58f9e132010-09-05 00:04:01 +000016 printf("%s", c); // expected-warning{{implicitly declaring C library function 'printf' with type 'int (const char *, ...)'}} \
Douglas Gregora316e7b2009-02-14 00:32:47 +000017 // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
Ted Kremenek8aefcbf2007-11-19 06:38:23 +000018}
Ted Kremenek74c43a02007-11-20 03:03:00 +000019
Chris Lattnere0303582010-01-09 20:43:19 +000020int f();
21
Ted Kremenek49a2fd22008-04-14 15:56:17 +000022void f3() {
Ted Kremenek0fdf06e2008-03-19 07:31:52 +000023 int r;
24 if ((r = f()) != 0) { // no-warning
25 int y = r; // no-warning
26 printf("the error is: %d\n", y);
27 }
Ted Kremenek74c43a02007-11-20 03:03:00 +000028}
Ted Kremenek49a2fd22008-04-14 15:56:17 +000029
30void f4(int k) {
31
32 k = 1;
33
34 if (k)
35 f1();
36
Ted Kremenek1a654b62008-06-20 21:45:25 +000037 k = 2; // expected-warning {{never read}}
Ted Kremenek49a2fd22008-04-14 15:56:17 +000038}
Ted Kremenek93fab7c2009-11-22 20:26:21 +000039
Ted Kremenekf87821c2008-04-15 18:37:29 +000040void f5() {
41
42 int x = 4; // no-warning
Ted Kremenekebd42f42010-03-18 01:22:39 +000043 int *p = &x; // expected-warning{{never read}} expected-warning{{unused variable 'p'}}
Ted Kremenekf87821c2008-04-15 18:37:29 +000044
Ted Kremeneka23157e2008-05-05 23:12:21 +000045}
46
47int f6() {
48
49 int x = 4;
Ted Kremenek1a654b62008-06-20 21:45:25 +000050 ++x; // expected-warning{{never read}}
Ted Kremeneka23157e2008-05-05 23:12:21 +000051 return 1;
52}
Ted Kremenek1a654b62008-06-20 21:45:25 +000053
54int f7(int *p) {
55 // This is allowed for defensive programming.
56 p = 0; // no-warning
57 return 1;
58}
59
Ted Kremenek93fab7c2009-11-22 20:26:21 +000060int f7b(int *p) {
61 // This is allowed for defensive programming.
62 p = (0); // no-warning
63 return 1;
64}
65
66int f7c(int *p) {
67 // This is allowed for defensive programming.
68 p = (void*) 0; // no-warning
69 return 1;
70}
71
72int f7d(int *p) {
73 // This is allowed for defensive programming.
74 p = (void*) (0); // no-warning
75 return 1;
76}
77
Ted Kremenek56b1f712011-01-13 20:58:56 +000078// Don't warn for dead stores in nested expressions. We have yet
79// to see a real bug in this scenario.
Ted Kremenek1a654b62008-06-20 21:45:25 +000080int f8(int *p) {
Daniel Dunbar4489fe12008-08-05 00:07:51 +000081 extern int *baz();
Ted Kremenek56b1f712011-01-13 20:58:56 +000082 if ((p = baz())) // no-warning
Ted Kremenek1a654b62008-06-20 21:45:25 +000083 return 1;
84 return 0;
85}
86
Ted Kremenek2cfac222008-07-23 21:16:38 +000087int f9() {
88 int x = 4;
89 x = x + 10; // expected-warning{{never read}}
90 return 1;
91}
92
Ted Kremenek2cfac222008-07-23 21:16:38 +000093int f10() {
94 int x = 4;
95 x = 10 + x; // expected-warning{{never read}}
96 return 1;
97}
98
Ted Kremenek8b00b6e2008-07-23 23:18:43 +000099int f11() {
100 int x = 4;
Ted Kremenek380277e2008-10-15 05:23:41 +0000101 return x++; // expected-warning{{never read}}
Ted Kremenek8b00b6e2008-07-23 23:18:43 +0000102}
103
Ted Kremenek380277e2008-10-15 05:23:41 +0000104int f11b() {
105 int x = 4;
Ted Kremenek7f5fce72009-01-20 00:47:45 +0000106 return ((((++x)))); // no-warning
Ted Kremenek380277e2008-10-15 05:23:41 +0000107}
108
Ted Kremenekfc7ff552008-07-25 04:47:34 +0000109int f12a(int y) {
Ted Kremenekebd42f42010-03-18 01:22:39 +0000110 int x = y; // expected-warning{{unused variable 'x'}}
Ted Kremenekfc7ff552008-07-25 04:47:34 +0000111 return 1;
112}
113int f12b(int y) {
114 int x __attribute__((unused)) = y; // no-warning
115 return 1;
116}
Ted Kremenekebd42f42010-03-18 01:22:39 +0000117int f12c(int y) {
118 // Allow initialiation of scalar variables by parameters as a form of
119 // defensive programming.
120 int x = y; // no-warning
121 x = 1;
122 return x;
123}
Ted Kremenek2cfac222008-07-23 21:16:38 +0000124
Ted Kremenekefe88f52008-08-06 23:26:31 +0000125// Filed with PR 2630. This code should produce no warnings.
126int f13(void)
127{
128 int a = 1;
129 int b, c = b = a + a;
130
131 if (b > 0)
132 return (0);
133
134 return (a + b + c);
135}
136
Ted Kremenekb497ebd2008-09-04 21:52:52 +0000137// Filed with PR 2763.
Ted Kremenek84fa6b92008-09-26 05:52:45 +0000138int f14(int count) {
Ted Kremenekb497ebd2008-09-04 21:52:52 +0000139 int index, nextLineIndex;
140 for (index = 0; index < count; index = nextLineIndex+1) {
141 nextLineIndex = index+1; // no-warning
142 continue;
143 }
144 return index;
145}
Ted Kremenek84fa6b92008-09-26 05:52:45 +0000146
147// Test case for <rdar://problem/6248086>
148void f15(unsigned x, unsigned y) {
149 int count = x * y; // no-warning
Ted Kremenekebd42f42010-03-18 01:22:39 +0000150 int z[count]; // expected-warning{{unused variable 'z'}}
Ted Kremenek84fa6b92008-09-26 05:52:45 +0000151}
152
Ted Kremenek56b1f712011-01-13 20:58:56 +0000153// Don't warn for dead stores in nested expressions. We have yet
154// to see a real bug in this scenario.
Ted Kremenek610a09e2008-09-26 22:58:57 +0000155int f16(int x) {
156 x = x * 2;
Ted Kremenek56b1f712011-01-13 20:58:56 +0000157 x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{The left operand to '+' is always 0}} expected-warning{{The left operand to '*' is always 1}}
Ted Kremenekd2025e22008-09-26 23:05:47 +0000158 ? 5 : 8;
Ted Kremenek610a09e2008-09-26 22:58:57 +0000159 return x;
160}
161
Ted Kremenek3b587862009-01-09 22:15:01 +0000162// Self-assignments should not be flagged as dead stores.
Mike Stumpa5495ea2009-07-21 19:01:31 +0000163void f17() {
Ted Kremenek3b587862009-01-09 22:15:01 +0000164 int x = 1;
Tom Careef52bcb2010-08-24 21:09:07 +0000165 x = x;
Ted Kremenek3b587862009-01-09 22:15:01 +0000166}
Ted Kremenek7f5fce72009-01-20 00:47:45 +0000167
168// <rdar://problem/6506065>
169// The values of dead stores are only "consumed" in an enclosing expression
Mike Stumpcd7bf232009-07-17 01:04:31 +0000170// what that value is actually used. In other words, don't say "Although the
171// value stored to 'x' is used...".
Ted Kremenek7f5fce72009-01-20 00:47:45 +0000172int f18() {
173 int x = 0; // no-warning
174 if (1)
175 x = 10; // expected-warning{{Value stored to 'x' is never read}}
176 while (1)
177 x = 10; // expected-warning{{Value stored to 'x' is never read}}
178 do
179 x = 10; // expected-warning{{Value stored to 'x' is never read}}
180 while (1);
181
Ted Kremenek56b1f712011-01-13 20:58:56 +0000182 // Don't warn for dead stores in nested expressions. We have yet
183 // to see a real bug in this scenario.
184 return (x = 10); // no-warning
Ted Kremenek7f5fce72009-01-20 00:47:45 +0000185}
Ted Kremenekd3098ee2009-02-09 18:01:00 +0000186
187// PR 3514: false positive `dead initialization` warning for init to global
188// http://llvm.org/bugs/show_bug.cgi?id=3514
189extern const int MyConstant;
190int f19(void) {
191 int x = MyConstant; // no-warning
192 x = 1;
193 return x;
194}
195
Ted Kremenek28433ff2009-03-31 03:34:38 +0000196int f19b(void) { // This case is the same as f19.
Ted Kremenekd3098ee2009-02-09 18:01:00 +0000197 const int MyConstant = 0;
Ted Kremenek28433ff2009-03-31 03:34:38 +0000198 int x = MyConstant; // no-warning
Ted Kremenekd3098ee2009-02-09 18:01:00 +0000199 x = 1;
200 return x;
201}
Ted Kremenek632d1ec2009-03-23 22:30:58 +0000202
203void f20(void) {
204 int x = 1; // no-warning
205#pragma unused(x)
206}
207
Mike Stumpcd7bf232009-07-17 01:04:31 +0000208void halt() __attribute__((noreturn));
209int f21() {
210 int x = 4;
211
212 ++x; // expected-warning{{never read}}
213 if (1) {
214 halt();
215 (void)x;
216 }
217 return 1;
218}
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000219
220int j;
221void f22() {
222 int x = 4;
223 int y1 = 4;
224 int y2 = 4;
225 int y3 = 4;
226 int y4 = 4;
227 int y5 = 4;
228 int y6 = 4;
229 int y7 = 4;
230 int y8 = 4;
231 int y9 = 4;
232 int y10 = 4;
Mike Stump5f203632009-07-21 00:38:52 +0000233 int y11 = 4;
234 int y12 = 4;
Mike Stumpfefb9f72009-07-21 01:12:51 +0000235 int y13 = 4;
236 int y14 = 4;
237 int y15 = 4;
Mike Stump8f9893a2009-07-21 01:27:50 +0000238 int y16 = 4;
239 int y17 = 4;
240 int y18 = 4;
Mike Stump22cd6582009-07-21 01:46:17 +0000241 int y19 = 4;
242 int y20 = 4;
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000243
244 ++x; // expected-warning{{never read}}
245 ++y1;
246 ++y2;
247 ++y3;
248 ++y4;
249 ++y5;
250 ++y6;
251 ++y7;
252 ++y8;
253 ++y9;
254 ++y10;
Mike Stump5f203632009-07-21 00:38:52 +0000255 ++y11;
256 ++y12;
Mike Stumpfefb9f72009-07-21 01:12:51 +0000257 ++y13;
258 ++y14;
259 ++y15;
Mike Stump8f9893a2009-07-21 01:27:50 +0000260 ++y16;
261 ++y17;
262 ++y18;
Mike Stump22cd6582009-07-21 01:46:17 +0000263 ++y19;
264 ++y20;
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000265
266 switch (j) {
267 case 1:
268 if (0)
269 (void)x;
270 if (1) {
271 (void)y1;
272 return;
273 }
274 (void)x;
275 break;
276 case 2:
277 if (0)
278 (void)x;
279 else {
280 (void)y2;
281 return;
282 }
283 (void)x;
284 break;
285 case 3:
286 if (1) {
287 (void)y3;
288 return;
289 } else
290 (void)x;
291 (void)x;
292 break;
293 case 4:
294 0 ? : ((void)y4, ({ return; }));
295 (void)x;
296 break;
297 case 5:
298 1 ? : (void)x;
299 0 ? (void)x : ((void)y5, ({ return; }));
300 (void)x;
301 break;
302 case 6:
303 1 ? ((void)y6, ({ return; })) : (void)x;
304 (void)x;
305 break;
306 case 7:
307 (void)(0 && x);
308 (void)y7;
Argyrios Kyrtzidis1b2ad2f2010-09-19 23:03:35 +0000309 (void)(0 || (y8, ({ return; }), 1)); // expected-warning {{expression result unused}}
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000310 (void)x;
311 break;
312 case 8:
Argyrios Kyrtzidis1b2ad2f2010-09-19 23:03:35 +0000313 (void)(1 && (y9, ({ return; }), 1)); // expected-warning {{expression result unused}}
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000314 (void)x;
315 break;
316 case 9:
317 (void)(1 || x);
318 (void)y10;
Mike Stump5f203632009-07-21 00:38:52 +0000319 break;
320 case 10:
Mike Stump5f203632009-07-21 00:38:52 +0000321 while (0) {
322 (void)x;
323 }
Mike Stump8f9893a2009-07-21 01:27:50 +0000324 (void)y11;
Mike Stump5f203632009-07-21 00:38:52 +0000325 break;
Mike Stump8f9893a2009-07-21 01:27:50 +0000326 case 11:
327 while (1) {
328 (void)y12;
Mike Stumpfefb9f72009-07-21 01:12:51 +0000329 }
330 (void)x;
331 break;
Mike Stump8f9893a2009-07-21 01:27:50 +0000332 case 12:
333 do {
334 (void)y13;
335 } while (0);
336 (void)y14;
337 break;
338 case 13:
339 do {
340 (void)y15;
341 } while (1);
342 (void)x;
343 break;
Mike Stumpfefb9f72009-07-21 01:12:51 +0000344 case 14:
Mike Stump8f9893a2009-07-21 01:27:50 +0000345 for (;;) {
346 (void)y16;
347 }
348 (void)x;
349 break;
350 case 15:
351 for (;1;) {
352 (void)y17;
353 }
354 (void)x;
355 break;
356 case 16:
Mike Stumpfefb9f72009-07-21 01:12:51 +0000357 for (;0;) {
358 (void)x;
359 }
Mike Stump8f9893a2009-07-21 01:27:50 +0000360 (void)y18;
Mike Stumpfefb9f72009-07-21 01:12:51 +0000361 break;
Mike Stump22cd6582009-07-21 01:46:17 +0000362 case 17:
363 __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
364 (void)x;
365 break;
366 case 19:
367 __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
368 (void)x;
369 break;
Mike Stumpe5af3ce2009-07-20 23:24:15 +0000370 }
371}
Ted Kremenek3a976342009-11-26 06:55:36 +0000372
373void f23_aux(const char* s);
374void f23(int argc, char **argv) {
375 int shouldLog = (argc > 1); // no-warning
376 ^{
377 if (shouldLog) f23_aux("I did too use it!\n");
378 else f23_aux("I shouldn't log. Wait.. d'oh!\n");
379 }();
380}
381
382void f23_pos(int argc, char **argv) {
Ted Kremenekebd42f42010-03-18 01:22:39 +0000383 int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} expected-warning{{unused variable 'shouldLog'}}
Ted Kremenek3a976342009-11-26 06:55:36 +0000384 ^{
385 f23_aux("I did too use it!\n");
386 }();
387}
Ted Kremenek9a0459c2009-12-01 23:04:14 +0000388
389void f24_A(int y) {
390 // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
391 int x = (y > 2); // no-warning
392 ^ {
Ted Kremenekebd42f42010-03-18 01:22:39 +0000393 int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}} expected-warning{{unused variable 'z'}}
Ted Kremenek9a0459c2009-12-01 23:04:14 +0000394 }();
395}
396
397void f24_B(int y) {
398 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
399 __block int x = (y > 2); // no-warning
400 ^{
401 // FIXME: This should eventually be a dead store since it is never read either.
402 x = 5; // no-warning
403 }();
404}
405
406int f24_C(int y) {
407 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
408 __block int x = (y > 2); // no-warning
409 ^{
410 x = 5; // no-warning
411 }();
412 return x;
413}
414
415int f24_D(int y) {
416 __block int x = (y > 2); // no-warning
417 ^{
418 if (y > 4)
419 x = 5; // no-warning
420 }();
421 return x;
422}
423
Ted Kremenek74635d82009-12-03 00:46:16 +0000424// This example shows that writing to a variable captured by a block means that it might
425// not be dead.
426int f25(int y) {
427 __block int x = (y > 2);
428 __block int z = 0;
429 void (^foo)() = ^{ z = x + y; };
430 x = 4; // no-warning
431 foo();
432 return z;
433}
434
435// This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
436// stores for variables that are just marked '__block' is overly conservative.
437int f25_b(int y) {
438 // FIXME: we should eventually report a dead store here.
439 __block int x = (y > 2);
440 __block int z = 0;
441 x = 4; // no-warning
442 return z;
443}
444
Ted Kremenek2cfe28b2010-03-10 00:18:11 +0000445int f26_nestedblocks() {
446 int z;
447 z = 1;
448 __block int y = 0;
449 ^{
450 int k;
451 k = 1; // expected-warning{{Value stored to 'k' is never read}}
452 ^{
453 y = z + 1;
454 }();
455 }();
456 return y;
457}
458
Ted Kremenek3f64a0e2010-05-21 20:30:15 +0000459// The FOREACH macro in QT uses 'break' statements within statement expressions
460// placed within the increment code of for loops.
461void rdar8014335() {
462 for (int i = 0 ; i != 10 ; ({ break; })) {
463 for ( ; ; ({ ++i; break; })) ;
464 // Note that the next value stored to 'i' is never executed
465 // because the next statement to be executed is the 'break'
466 // in the increment code of the first loop.
Ted Kremenek3e5637f2010-07-27 18:49:08 +0000467 i = i * 3; // expected-warning{{Value stored to 'i' is never read}} expected-warning{{The left operand to '*' is always 1}}
Ted Kremenek3f64a0e2010-05-21 20:30:15 +0000468 }
469}
470
Ted Kremenek334c1952010-08-17 21:00:06 +0000471// <rdar://problem/8320674> NullStmts followed by do...while() can lead to disconnected CFG
472//
473// This previously caused bogus dead-stores warnings because the body of the first do...while was
474// disconnected from the entry of the function.
475typedef struct { float r; float i; } s_rdar8320674;
476typedef struct { s_rdar8320674 x[1]; } s2_rdar8320674;
477
478void rdar8320674(s_rdar8320674 *z, unsigned y, s2_rdar8320674 *st, int m)
479{
480 s_rdar8320674 * z2;
481 s_rdar8320674 * tw1 = st->x;
482 s_rdar8320674 t;
483 z2 = z + m;
484 do{
485 ; ;
486 do{ (t).r = (*z2).r*(*tw1).r - (*z2).i*(*tw1).i; (t).i = (*z2).r*(*tw1).i + (*z2).i*(*tw1).r; }while(0);
487 tw1 += y;
488 do { (*z2).r=(*z).r-(t).r; (*z2).i=(*z).i-(t).i; }while(0);
489 do { (*z).r += (t).r; (*z).i += (t).i; }while(0);
490 ++z2;
491 ++z;
492 }while (--m);
493}
494