150 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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}}
 | |
| }
 | |
| 
 | |
| void consume_const_ref(const int &n);
 | |
| int test_const_ref() {
 | |
|   int n; // expected-note {{variable}}
 | |
|   consume_const_ref(n);
 | |
|   return n; // expected-warning {{uninitialized when used here}}
 | |
| }
 | 
