1// RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -verify %s
2// RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
3
4bool maybe();
5
6int test_if_false(bool b) {
7  int x; // expected-note {{variable}}
8  if (b) // expected-warning {{whenever 'if' condition is false}} \
9         // expected-note {{remove the 'if' if its condition is always true}}
10    x = 1;
11  return x; // expected-note {{uninitialized use}}
12}
13
14// CHECK: fix-it:"{{.*}}":{8:3-10:5}:""
15// CHECK: fix-it:"{{.*}}":{7:8-7:8}:" = 0"
16
17
18int test_if_true(bool b) {
19  int x; // expected-note {{variable}}
20  if (b) {} // expected-warning {{whenever 'if' condition is true}} \
21            // expected-note {{remove the 'if' if its condition is always false}}
22  else x = 1;
23  return x; // expected-note {{uninitialized use}}
24}
25
26// CHECK: fix-it:"{{.*}}":{20:3-22:8}:""
27// CHECK: fix-it:"{{.*}}":{19:8-19:8}:" = 0"
28
29
30int test_while_false(bool b) {
31  int x; // expected-note {{variable}}
32  while (b) { // expected-warning {{whenever 'while' loop exits because its condition is false}} \
33              // expected-note {{remove the condition if it is always true}}
34    if (maybe()) {
35      x = 1;
36      break;
37    }
38  };
39  return x; // expected-note {{uninitialized use}}
40}
41
42// CHECK: fix-it:"{{.*}}":{32:10-32:11}:"true"
43// CHECK: fix-it:"{{.*}}":{31:8-31:8}:" = 0"
44
45
46int test_while_true(bool b) {
47  int x; // expected-note {{variable}}
48  while (b) { // expected-warning {{whenever 'while' loop is entered}} \
49              // expected-note {{remove the condition if it is always false}}
50label:
51    return x; // expected-note {{uninitialized use}}
52  }
53  x = 0;
54  goto label;
55}
56
57// CHECK: fix-it:"{{.*}}":{48:10-48:11}:"false"
58// CHECK: fix-it:"{{.*}}":{47:8-47:8}:" = 0"
59
60
61int test_do_while_false(bool b) {
62  int x; // expected-note {{variable}}
63  do {
64    if (maybe()) {
65      x = 1;
66      break;
67    }
68  } while (b); // expected-warning {{whenever 'do' loop exits because its condition is false}} \
69               // expected-note {{remove the condition if it is always true}}
70  return x; // expected-note {{uninitialized use}}
71}
72
73// CHECK: fix-it:"{{.*}}":{68:12-68:13}:"true"
74// CHECK: fix-it:"{{.*}}":{62:8-62:8}:" = 0"
75
76
77int test_do_while_true(bool b) {
78  int x; // expected-note {{variable}}
79goto label2;
80  do {
81label1:
82    return x; // expected-note {{uninitialized use}}
83label2: ;
84  } while (b); // expected-warning {{whenever 'do' loop condition is true}} \
85               // expected-note {{remove the condition if it is always false}}
86  x = 0;
87  goto label1;
88}
89
90// CHECK: fix-it:"{{.*}}":{84:12-84:13}:"false"
91// CHECK: fix-it:"{{.*}}":{78:8-78:8}:" = 0"
92
93
94int test_for_false(int k) {
95  int x; // expected-note {{variable}}
96  for (int n = 0;
97       n < k; // expected-warning {{whenever 'for' loop exits because its condition is false}} \
98              // expected-note {{remove the condition if it is always true}}
99       ++n) {
100    if (maybe()) {
101      x = n;
102      break;
103    }
104  }
105  return x; // expected-note {{uninitialized use}}
106}
107
108// CHECK: fix-it:"{{.*}}":{97:8-97:13}:""
109// CHECK: fix-it:"{{.*}}":{95:8-95:8}:" = 0"
110
111
112int test_for_true(int k) {
113  int x; // expected-note {{variable}}
114  int n = 0;
115  for (;
116       n < k; // expected-warning {{whenever 'for' loop is entered}} \
117              // expected-note {{remove the condition if it is always false}}
118       ++n) {
119label:
120    return x; // expected-note {{uninitialized use}}
121  }
122  x = 1;
123  goto label;
124}
125
126// CHECK: fix-it:"{{.*}}":{116:8-116:13}:"false"
127// CHECK: fix-it:"{{.*}}":{113:8-113:8}:" = 0"
128
129
130int test_for_range_false(int k) {
131  int arr[3] = { 1, 2, 3 };
132  int x;
133  for (int &a : arr) { // no-warning, condition was not explicitly specified
134    if (a == k) {
135      x = &a - arr;
136      break;
137    }
138  }
139  return x;
140}
141
142
143
144
145
146int test_for_range_true(int k) {
147  int arr[3] = { 1, 2, 3 };
148  int x; // expected-note {{variable}}
149  for (int &a : arr) { // expected-warning {{variable 'x' is used uninitialized whenever 'for' loop is entered}}
150    goto label;
151  }
152  x = 0;
153label:
154  return x; // expected-note {{uninitialized use}}
155}
156
157
158
159
160
161int test_conditional_false(int k) {
162  int x; // expected-note {{variable}}
163  (void)(
164      maybe() // expected-warning {{whenever '?:' condition is false}} \
165              // expected-note {{remove the '?:' if its condition is always true}}
166      ? x = 1 : 0);
167  return x; // expected-note {{uninitialized use}}
168}
169
170// CHECK: fix-it:"{{.*}}":{164:7-166:9}:""
171// CHECK: fix-it:"{{.*}}":{166:14-166:18}:""
172// CHECK: fix-it:"{{.*}}":{162:8-162:8}:" = 0"
173
174int test_conditional_true(int k) {
175  int x; // expected-note {{variable}}
176  (void)(
177      maybe() // expected-warning {{whenever '?:' condition is true}} \
178              // expected-note {{remove the '?:' if its condition is always false}}
179      ? 0 : x = 1);
180  return x; // expected-note {{uninitialized use}}
181}
182
183// CHECK: fix-it:"{{.*}}":{177:7-179:13}:""
184// CHECK: fix-it:"{{.*}}":{175:8-175:8}:" = 0"
185
186
187int test_logical_and_false(int k) {
188  int x; // expected-note {{variable}}
189  maybe() // expected-warning {{whenever '&&' condition is false}} \
190          // expected-note {{remove the '&&' if its condition is always true}}
191      && (x = 1);
192  return x; // expected-note {{uninitialized use}}
193}
194
195// CHECK: fix-it:"{{.*}}":{189:3-191:10}:""
196// CHECK: fix-it:"{{.*}}":{188:8-188:8}:" = 0"
197
198
199int test_logical_and_true(int k) {
200  int x; // expected-note {{variable}}
201  maybe() // expected-warning {{whenever '&&' condition is true}} \
202          // expected-note {{remove the '&&' if its condition is always false}}
203      && ({ goto skip_init; 0; });
204  x = 1;
205skip_init:
206  return x; // expected-note {{uninitialized use}}
207}
208
209// CHECK: fix-it:"{{.*}}":{201:3-203:34}:"false"
210// CHECK: fix-it:"{{.*}}":{200:8-200:8}:" = 0"
211
212
213int test_logical_or_false(int k) {
214  int x; // expected-note {{variable}}
215  maybe() // expected-warning {{whenever '||' condition is false}} \
216          // expected-note {{remove the '||' if its condition is always true}}
217      || ({ goto skip_init; 0; });
218  x = 1;
219skip_init:
220  return x; // expected-note {{uninitialized use}}
221}
222
223// CHECK: fix-it:"{{.*}}":{215:3-217:34}:"true"
224// CHECK: fix-it:"{{.*}}":{214:8-214:8}:" = 0"
225
226
227int test_logical_or_true(int k) {
228  int x; // expected-note {{variable}}
229  maybe() // expected-warning {{whenever '||' condition is true}} \
230          // expected-note {{remove the '||' if its condition is always false}}
231      || (x = 1);
232  return x; // expected-note {{uninitialized use}}
233}
234
235// CHECK: fix-it:"{{.*}}":{229:3-231:10}:""
236// CHECK: fix-it:"{{.*}}":{228:8-228:8}:" = 0"
237
238
239int test_switch_case(int k) {
240  int x; // expected-note {{variable}}
241  switch (k) {
242  case 0:
243    x = 0;
244    break;
245  case 1: // expected-warning {{whenever switch case is taken}}
246    break;
247  }
248  return x; // expected-note {{uninitialized use}}
249}
250
251// CHECK: fix-it:"{{.*}}":{240:8-240:8}:" = 0"
252
253
254
255int test_switch_default(int k) {
256  int x; // expected-note {{variable}}
257  switch (k) {
258  case 0:
259    x = 0;
260    break;
261  case 1:
262    x = 1;
263    break;
264  default: // expected-warning {{whenever switch default is taken}}
265    break;
266  }
267  return x; // expected-note {{uninitialized use}}
268}
269
270// CHECK: fix-it:"{{.*}}":{256:8-256:8}:" = 0"
271
272
273
274int test_switch_suppress_1(int k) {
275  int x;
276  switch (k) {
277  case 0:
278    x = 0;
279    break;
280  case 1:
281    x = 1;
282    break;
283  }
284  return x; // no-warning
285}
286
287
288
289
290
291int test_switch_suppress_2(int k) {
292  int x;
293  switch (k) {
294  case 0:
295  case 1:
296    switch (k) {
297    case 0:
298      return 0;
299    case 1:
300      return 1;
301    }
302  case 2:
303  case 3:
304    x = 1;
305  }
306  return x; // no-warning
307}
308
309
310
311
312
313int test_multiple_notes(int k) {
314  int x; // expected-note {{variable}}
315  if (k > 0) {
316    if (k == 5)
317      x = 1;
318    else if (k == 2) // expected-warning {{whenever 'if' condition is false}} \
319                     // expected-note {{remove the 'if' if its condition is always true}}
320      x = 2;
321  } else {
322    if (k == -5)
323      x = 3;
324    else if (k == -2) // expected-warning {{whenever 'if' condition is false}} \
325                      // expected-note {{remove the 'if' if its condition is always true}}
326      x = 4;
327  }
328  return x; // expected-note 2{{uninitialized use}}
329}
330
331// CHECK: fix-it:"{{.*}}":{324:10-326:7}:""
332// CHECK: fix-it:"{{.*}}":{318:10-320:7}:""
333// CHECK: fix-it:"{{.*}}":{314:8-314:8}:" = 0"
334
335int test_no_false_positive_1(int k) {
336  int x;
337  if (k)
338    x = 5;
339  while (!k)
340    maybe();
341  return x;
342}
343
344
345
346
347
348int test_no_false_positive_2() {
349  int x;
350  bool b = false;
351  if (maybe()) {
352    x = 5;
353    b = true;
354  }
355  return b ? x : 0;
356}
357
358
359
360
361
362void test_null_pred_succ() {
363  int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_null_pred_succ' is called}}
364  if (0)
365    foo: x = 0;
366  if (x) // expected-note {{use}}
367    goto foo;
368}
369
370
371
372
373void foo();
374int PR13360(bool b) {
375  int x; // expected-note {{variable}}
376  if (b) { // expected-warning {{variable 'x' is used uninitialized whenever 'if' condition is true}} expected-note {{remove}}
377    do {
378      foo();
379    } while (0);
380  } else {
381    x = 1;
382  }
383  return x; // expected-note {{uninitialized use occurs here}}
384}
385
386// CHECK: fix-it:"{{.*}}":{376:3-380:10}:""
387// CHECK: fix-it:"{{.*}}":{375:8-375:8}:" = 0"
388
389void test_jump_init() {
390goto later;
391  int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_jump_init'}}
392later:
393  while (x) x = 0; // expected-note {{use}}
394}
395
396void PR16054() {
397  int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'PR16054}}
398  while (x != 0) { // expected-note {{use}}
399    (void)&x;
400  }
401}
402
403void test_loop_uninit() {
404  for (int n = 0; n < 10; ++n) {
405    int k; // expected-warning {{variable 'k' is used uninitialized whenever its declaration is reached}} expected-note {{variable}}
406    do {
407      k = k + 1; // expected-note {{use}}
408    } while (k != 5);
409  }
410}
411
412// FIXME: We should warn here, because the variable is used uninitialized
413// the first time we encounter the use.
414void test_loop_with_assignment() {
415  double d;
416  for (int n = 0; n < 10; ++n) {
417    d = d + n;
418  }
419}
420
421// FIXME: We should warn here, because the variable is used uninitialized
422// the first time we encounter the use.
423void test_loop_with_ref_bind() {
424  double d;
425  for (int n = 0; n < 10; ++n) {
426    d += n;
427    const double &r = d;
428  }
429}
430