diff options
Diffstat (limited to 'clang/test/SemaCXX/uninit-variables.cpp')
-rw-r--r-- | clang/test/SemaCXX/uninit-variables.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/uninit-variables.cpp b/clang/test/SemaCXX/uninit-variables.cpp new file mode 100644 index 0000000..eb6428d --- /dev/null +++ b/clang/test/SemaCXX/uninit-variables.cpp @@ -0,0 +1,143 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify + +// Stub out types for 'typeid' to work. +namespace std { class type_info {}; } + +int test1_aux(int &x); +int test1() { + int x; + test1_aux(x); + return x; // no-warning +} + +int test2_aux() { + int x; + int &y = x; + return x; // no-warning +} + +// Don't warn on unevaluated contexts. +void unevaluated_tests() { + int x; + (void)sizeof(x); + (void)typeid(x); +} + +// Warn for glvalue arguments to typeid whose type is polymorphic. +struct A { virtual ~A() {} }; +void polymorphic_test() { + A *a; // expected-note{{initialize the variable 'a' to silence this warning}} + (void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here}} +} + +// Handle cases where the CFG may constant fold some branches, thus +// mitigating the need for some path-sensitivity in the analysis. +unsigned test3_aux(); +unsigned test3() { + unsigned x = 0; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + return x; + } + return x; +} +unsigned test3_b() { + unsigned x ; + const bool flag = true; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // no-warning +} +unsigned test3_c() { + unsigned x; // expected-note{{initialize the variable 'x' to silence this warning}} + const bool flag = false; + if (flag && (x = test3_aux()) == 0) { + x = 1; + } + return x; // expected-warning{{variable 'x' is uninitialized when used here}} +} + +enum test4_A { + test4_A_a, test_4_A_b +}; +test4_A test4() { + test4_A a; // expected-note{{variable 'a' is declared here}} + return a; // expected-warning{{variable 'a' is uninitialized when used here}} +} + +// Test variables getting invalidated by function calls with reference arguments +// *AND* there are multiple invalidated arguments. +void test5_aux(int &, int &); + +int test5() { + int x, y; + test5_aux(x, y); + return x + y; // no-warning +} + +// This test previously crashed Sema. +class Rdar9188004A { +public: + virtual ~Rdar9188004A(); +}; + +template< typename T > class Rdar9188004B : public Rdar9188004A { +virtual double *foo(Rdar9188004B *next) const { + double *values = next->foo(0); + try { + } + catch(double e) { + values[0] = e; + } + return 0; + } +}; +class Rdar9188004C : public Rdar9188004B<Rdar9188004A> { + virtual void bar(void) const; +}; +void Rdar9188004C::bar(void) const {} + +// Don't warn about uninitialized variables in unreachable code. +void PR9625() { + if (false) { + int x; + (void)static_cast<float>(x); // no-warning + } +} + +// Don't warn about variables declared in "catch" +void RDar9251392_bar(const char *msg); + +void RDar9251392() { + try { + throw "hi"; + } + catch (const char* msg) { + RDar9251392_bar(msg); // no-warning + } +} + +// Test handling of "no-op" casts. +void test_noop_cast() +{ + int x = 1; + int y = (int&)x; // no-warning +} + +void test_noop_cast2() { + int x; // expected-note {{initialize the variable 'x' to silence this warning}} + int y = (int&)x; // expected-warning {{uninitialized when used here}} +} + +// Test handling of bit casts. +void test_bitcasts() { + int x = 1; + int y = (float &)x; // no-warning +} + +void test_bitcasts_2() { + int x; // expected-note {{initialize the variable 'x' to silence this warning}} + int y = (float &)x; // expected-warning {{uninitialized when used here}} +} + |