430 lines
10 KiB
C++
430 lines
10 KiB
C++
// 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;
|
|
}
|
|
}
|