|  | // RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -verify %s | 
|  | // RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s | 
|  |  | 
|  | bool maybe(); | 
|  |  | 
|  | int test_if_false(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | if (b) // expected-warning {{whenever 'if' condition is false}} \ | 
|  | // expected-note {{remove the 'if' if its condition is always true}} | 
|  | x = 1; | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{8:3-10:5}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{7:8-7:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_if_true(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | if (b) {} // expected-warning {{whenever 'if' condition is true}} \ | 
|  | // expected-note {{remove the 'if' if its condition is always false}} | 
|  | else x = 1; | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{20:3-22:8}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{19:8-19:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_while_false(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | while (b) { // expected-warning {{whenever 'while' loop exits because its condition is false}} \ | 
|  | // expected-note {{remove the condition if it is always true}} | 
|  | if (maybe()) { | 
|  | x = 1; | 
|  | break; | 
|  | } | 
|  | }; | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{32:10-32:11}:"true" | 
|  | // CHECK: fix-it:"{{.*}}":{31:8-31:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_while_true(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | while (b) { // expected-warning {{whenever 'while' loop is entered}} \ | 
|  | // expected-note {{remove the condition if it is always false}} | 
|  | label: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  | x = 0; | 
|  | goto label; | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{48:10-48:11}:"false" | 
|  | // CHECK: fix-it:"{{.*}}":{47:8-47:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_do_while_false(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | do { | 
|  | if (maybe()) { | 
|  | x = 1; | 
|  | break; | 
|  | } | 
|  | } while (b); // expected-warning {{whenever 'do' loop exits because its condition is false}} \ | 
|  | // expected-note {{remove the condition if it is always true}} | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{68:12-68:13}:"true" | 
|  | // CHECK: fix-it:"{{.*}}":{62:8-62:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_do_while_true(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | goto label2; | 
|  | do { | 
|  | label1: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | label2: ; | 
|  | } while (b); // expected-warning {{whenever 'do' loop condition is true}} \ | 
|  | // expected-note {{remove the condition if it is always false}} | 
|  | x = 0; | 
|  | goto label1; | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{84:12-84:13}:"false" | 
|  | // CHECK: fix-it:"{{.*}}":{78:8-78:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_for_false(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | for (int n = 0; | 
|  | n < k; // expected-warning {{whenever 'for' loop exits because its condition is false}} \ | 
|  | // expected-note {{remove the condition if it is always true}} | 
|  | ++n) { | 
|  | if (maybe()) { | 
|  | x = n; | 
|  | break; | 
|  | } | 
|  | } | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{97:8-97:13}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{95:8-95:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_for_true(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | int n = 0; | 
|  | for (; | 
|  | n < k; // expected-warning {{whenever 'for' loop is entered}} \ | 
|  | // expected-note {{remove the condition if it is always false}} | 
|  | ++n) { | 
|  | label: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  | x = 1; | 
|  | goto label; | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{116:8-116:13}:"false" | 
|  | // CHECK: fix-it:"{{.*}}":{113:8-113:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_for_range_false(int k) { | 
|  | int arr[3] = { 1, 2, 3 }; | 
|  | int x; | 
|  | for (int &a : arr) { // no-warning, condition was not explicitly specified | 
|  | if (a == k) { | 
|  | x = &a - arr; | 
|  | break; | 
|  | } | 
|  | } | 
|  | return x; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_for_range_true(int k) { | 
|  | int arr[3] = { 1, 2, 3 }; | 
|  | int x; // expected-note {{variable}} | 
|  | for (int &a : arr) { // expected-warning {{variable 'x' is used uninitialized whenever 'for' loop is entered}} | 
|  | goto label; | 
|  | } | 
|  | x = 0; | 
|  | label: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_conditional_false(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | (void)( | 
|  | maybe() // expected-warning {{whenever '?:' condition is false}} \ | 
|  | // expected-note {{remove the '?:' if its condition is always true}} | 
|  | ? x = 1 : 0); | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{164:7-166:9}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{166:14-166:18}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{162:8-162:8}:" = 0" | 
|  |  | 
|  | int test_conditional_true(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | (void)( | 
|  | maybe() // expected-warning {{whenever '?:' condition is true}} \ | 
|  | // expected-note {{remove the '?:' if its condition is always false}} | 
|  | ? 0 : x = 1); | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{177:7-179:13}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{175:8-175:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_logical_and_false(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | maybe() // expected-warning {{whenever '&&' condition is false}} \ | 
|  | // expected-note {{remove the '&&' if its condition is always true}} | 
|  | && (x = 1); | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{189:3-191:10}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{188:8-188:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_logical_and_true(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | maybe() // expected-warning {{whenever '&&' condition is true}} \ | 
|  | // expected-note {{remove the '&&' if its condition is always false}} | 
|  | && ({ goto skip_init; 0; }); | 
|  | x = 1; | 
|  | skip_init: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{201:3-203:34}:"false" | 
|  | // CHECK: fix-it:"{{.*}}":{200:8-200:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_logical_or_false(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | maybe() // expected-warning {{whenever '||' condition is false}} \ | 
|  | // expected-note {{remove the '||' if its condition is always true}} | 
|  | || ({ goto skip_init; 0; }); | 
|  | x = 1; | 
|  | skip_init: | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{215:3-217:34}:"true" | 
|  | // CHECK: fix-it:"{{.*}}":{214:8-214:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_logical_or_true(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | maybe() // expected-warning {{whenever '||' condition is true}} \ | 
|  | // expected-note {{remove the '||' if its condition is always false}} | 
|  | || (x = 1); | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{229:3-231:10}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{228:8-228:8}:" = 0" | 
|  |  | 
|  |  | 
|  | int test_switch_case(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | switch (k) { | 
|  | case 0: | 
|  | x = 0; | 
|  | break; | 
|  | case 1: // expected-warning {{whenever switch case is taken}} | 
|  | break; | 
|  | } | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{240:8-240:8}:" = 0" | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_switch_default(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | switch (k) { | 
|  | case 0: | 
|  | x = 0; | 
|  | break; | 
|  | case 1: | 
|  | x = 1; | 
|  | break; | 
|  | default: // expected-warning {{whenever switch default is taken}} | 
|  | break; | 
|  | } | 
|  | return x; // expected-note {{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{256:8-256:8}:" = 0" | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_switch_suppress_1(int k) { | 
|  | int x; | 
|  | switch (k) { | 
|  | case 0: | 
|  | x = 0; | 
|  | break; | 
|  | case 1: | 
|  | x = 1; | 
|  | break; | 
|  | } | 
|  | return x; // no-warning | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_switch_suppress_2(int k) { | 
|  | int x; | 
|  | switch (k) { | 
|  | case 0: | 
|  | case 1: | 
|  | switch (k) { | 
|  | case 0: | 
|  | return 0; | 
|  | case 1: | 
|  | return 1; | 
|  | } | 
|  | case 2: | 
|  | case 3: | 
|  | x = 1; | 
|  | } | 
|  | return x; // no-warning | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_multiple_notes(int k) { | 
|  | int x; // expected-note {{variable}} | 
|  | if (k > 0) { | 
|  | if (k == 5) | 
|  | x = 1; | 
|  | else if (k == 2) // expected-warning {{whenever 'if' condition is false}} \ | 
|  | // expected-note {{remove the 'if' if its condition is always true}} | 
|  | x = 2; | 
|  | } else { | 
|  | if (k == -5) | 
|  | x = 3; | 
|  | else if (k == -2) // expected-warning {{whenever 'if' condition is false}} \ | 
|  | // expected-note {{remove the 'if' if its condition is always true}} | 
|  | x = 4; | 
|  | } | 
|  | return x; // expected-note 2{{uninitialized use}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{324:10-326:7}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{318:10-320:7}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{314:8-314:8}:" = 0" | 
|  |  | 
|  | int test_no_false_positive_1(int k) { | 
|  | int x; | 
|  | if (k) | 
|  | x = 5; | 
|  | while (!k) | 
|  | maybe(); | 
|  | return x; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | int test_no_false_positive_2() { | 
|  | int x; | 
|  | bool b = false; | 
|  | if (maybe()) { | 
|  | x = 5; | 
|  | b = true; | 
|  | } | 
|  | return b ? x : 0; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | void test_null_pred_succ() { | 
|  | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_null_pred_succ' is called}} | 
|  | if (0) | 
|  | foo: x = 0; | 
|  | if (x) // expected-note {{use}} | 
|  | goto foo; | 
|  | } | 
|  |  | 
|  |  | 
|  |  | 
|  |  | 
|  | void foo(); | 
|  | int PR13360(bool b) { | 
|  | int x; // expected-note {{variable}} | 
|  | if (b) { // expected-warning {{variable 'x' is used uninitialized whenever 'if' condition is true}} expected-note {{remove}} | 
|  | do { | 
|  | foo(); | 
|  | } while (0); | 
|  | } else { | 
|  | x = 1; | 
|  | } | 
|  | return x; // expected-note {{uninitialized use occurs here}} | 
|  | } | 
|  |  | 
|  | // CHECK: fix-it:"{{.*}}":{376:3-380:10}:"" | 
|  | // CHECK: fix-it:"{{.*}}":{375:8-375:8}:" = 0" | 
|  |  | 
|  | void test_jump_init() { | 
|  | goto later; | 
|  | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_jump_init'}} | 
|  | later: | 
|  | while (x) x = 0; // expected-note {{use}} | 
|  | } | 
|  |  | 
|  | void PR16054() { | 
|  | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'PR16054}} | 
|  | while (x != 0) { // expected-note {{use}} | 
|  | (void)&x; | 
|  | } | 
|  | } | 
|  |  | 
|  | void test_loop_uninit() { | 
|  | for (int n = 0; n < 10; ++n) { | 
|  | int k; // expected-warning {{variable 'k' is used uninitialized whenever its declaration is reached}} expected-note {{variable}} | 
|  | do { | 
|  | k = k + 1; // expected-note {{use}} | 
|  | } while (k != 5); | 
|  | } | 
|  | } | 
|  |  | 
|  | // FIXME: We should warn here, because the variable is used uninitialized | 
|  | // the first time we encounter the use. | 
|  | void test_loop_with_assignment() { | 
|  | double d; | 
|  | for (int n = 0; n < 10; ++n) { | 
|  | d = d + n; | 
|  | } | 
|  | } | 
|  |  | 
|  | // FIXME: We should warn here, because the variable is used uninitialized | 
|  | // the first time we encounter the use. | 
|  | void test_loop_with_ref_bind() { | 
|  | double d; | 
|  | for (int n = 0; n < 10; ++n) { | 
|  | d += n; | 
|  | const double &r = d; | 
|  | } | 
|  | } |