diff options
Diffstat (limited to 'test/Sema/uninit-variables.c')
-rw-r--r-- | test/Sema/uninit-variables.c | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index d62186d..634ae0d 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -39,17 +39,19 @@ int test6() { int test7(int y) { int x; // expected-note{{initialize the variable 'x' to silence this warning}} - if (y) + if (y) // expected-warning{{variable 'x' is used uninitialized whenever 'if' condition is false}} \ + // expected-note{{remove the 'if' if its condition is always true}} x = 1; - return x; // expected-warning{{variable 'x' may be uninitialized when used here}} + return x; // expected-note{{uninitialized use occurs here}} } int test7b(int y) { int x = x; // expected-note{{variable 'x' is declared here}} if (y) x = 1; - // Warn with "may be uninitialized" here (not "is uninitialized"), since the - // self-initialization is intended to suppress a -Wuninitialized warning. + // Warn with "may be uninitialized" here (not "is sometimes uninitialized"), + // since the self-initialization is intended to suppress a -Wuninitialized + // warning. return x; // expected-warning{{variable 'x' may be uninitialized when used here}} } @@ -150,15 +152,15 @@ int test19() { int test20() { int z; // expected-note{{initialize the variable 'z' to silence this warning}} - if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) - return z; // expected-warning{{variable 'z' may be uninitialized when used here}} + if ((test19_aux1() + test19_aux2() && test19_aux1()) || test19_aux3(&z)) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} + return z; // expected-note {{uninitialized use occurs here}} return 0; } int test21(int x, int y) { int z; // expected-note{{initialize the variable 'z' to silence this warning}} - if ((x && y) || test19_aux3(&z) || test19_aux2()) - return z; // expected-warning{{variable 'z' may be uninitialized when used here}} + if ((x && y) || test19_aux3(&z) || test19_aux2()) // expected-warning {{variable 'z' is used uninitialized whenever '||' condition is true}} expected-note {{remove the '||' if its condition is always false}} + return z; // expected-note {{uninitialized use occurs here}} return 0; } @@ -293,8 +295,9 @@ int test40(int x) { int test41(int x) { int y; // expected-note{{initialize the variable 'y' to silence this warning}} - if (x) y = 1; // no-warning - return y; // expected-warning {{variable 'y' may be uninitialized when used here}} + if (x) y = 1; // expected-warning{{variable 'y' is used uninitialized whenever 'if' condition is false}} \ + // expected-note{{remove the 'if' if its condition is always true}} + return y; // expected-note{{uninitialized use occurs here}} } void test42() { @@ -424,3 +427,84 @@ void rdar9432305(float *P) { for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}} P[i] = 0.0f; } + +// Test that fixits are not emitted inside macros. +#define UNINIT(T, x, y) T x; T y = x; +#define ASSIGN(T, x, y) T y = x; +void test54() { + UNINIT(int, a, b); // expected-warning {{variable 'a' is uninitialized when used here}} \ + // expected-note {{variable 'a' is declared here}} + int c; // expected-note {{initialize the variable 'c' to silence this warning}} + ASSIGN(int, c, d); // expected-warning {{variable 'c' is uninitialized when used here}} +} + +// Taking the address is fine +struct { struct { void *p; } a; } test55 = { { &test55.a }}; // no-warning +struct { struct { void *p; } a; } test56 = { { &(test56.a) }}; // no-warning + +void uninit_in_loop() { + int produce(void); + void consume(int); + for (int n = 0; n < 100; ++n) { + int k; // expected-note {{initialize}} + consume(k); // expected-warning {{variable 'k' is uninitialized}} + k = produce(); + } +} + +void uninit_in_loop_goto() { + int produce(void); + void consume(int); + for (int n = 0; n < 100; ++n) { + goto skip_decl; + int k; // expected-note {{initialize}} +skip_decl: + // FIXME: This should produce the 'is uninitialized' diagnostic, but we + // don't have enough information in the CFG to easily tell that the + // variable's scope has been left and re-entered. + consume(k); // expected-warning {{variable 'k' may be uninitialized}} + k = produce(); + } +} + +typedef char jmp_buf[256]; +extern int setjmp(jmp_buf env); // implicitly returns_twice + +void do_stuff_and_longjmp(jmp_buf env, int *result) __attribute__((noreturn)); + +int returns_twice() { + int a; // expected-note {{initialize}} + if (!a) { // expected-warning {{variable 'a' is uninitialized}} + jmp_buf env; + int b; + if (setjmp(env) == 0) { + do_stuff_and_longjmp(env, &b); + } else { + a = b; // no warning + } + } + return a; +} + +int compound_assign(int *arr, int n) { + int sum; // expected-note {{initialize}} + for (int i = 0; i < n; ++i) + sum += arr[i]; // expected-warning {{variable 'sum' is uninitialized}} + return sum / n; +} + +int compound_assign_2() { + int x; // expected-note {{initialize}} + return x += 1; // expected-warning {{variable 'x' is uninitialized}} +} + +int compound_assign_3() { + int x; // expected-note {{initialize}} + x *= 0; // expected-warning {{variable 'x' is uninitialized}} + return x; +} + +int self_init_in_cond(int *p) { + int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok + return n; +} |