1 | // RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify -std=c++1y |
2 | |
3 | // Stub out types for 'typeid' to work. |
4 | namespace std { class type_info {}; } |
5 | |
6 | int test1_aux(int &x); |
7 | int test1() { |
8 | int x; |
9 | test1_aux(x); |
10 | return x; // no-warning |
11 | } |
12 | |
13 | int test2_aux() { |
14 | int x; |
15 | int &y = x; |
16 | return x; // no-warning |
17 | } |
18 | |
19 | // Don't warn on unevaluated contexts. |
20 | void unevaluated_tests() { |
21 | int x; |
22 | (void)sizeof(x); |
23 | (void)typeid(x); |
24 | } |
25 | |
26 | // Warn for glvalue arguments to typeid whose type is polymorphic. |
27 | struct A { virtual ~A() {} }; |
28 | void polymorphic_test() { |
29 | A *a; // expected-note{{initialize the variable 'a' to silence this warning}} |
30 | (void)typeid(*a); // expected-warning{{variable 'a' is uninitialized when used here}} |
31 | } |
32 | |
33 | // Handle cases where the CFG may constant fold some branches, thus |
34 | // mitigating the need for some path-sensitivity in the analysis. |
35 | unsigned test3_aux(); |
36 | unsigned test3() { |
37 | unsigned x = 0; |
38 | const bool flag = true; |
39 | if (flag && (x = test3_aux()) == 0) { |
40 | return x; |
41 | } |
42 | return x; |
43 | } |
44 | unsigned test3_b() { |
45 | unsigned x ; |
46 | const bool flag = true; |
47 | if (flag && (x = test3_aux()) == 0) { |
48 | x = 1; |
49 | } |
50 | return x; // no-warning |
51 | } |
52 | unsigned test3_c() { |
53 | unsigned x; // expected-note{{initialize the variable 'x' to silence this warning}} |
54 | const bool flag = false; |
55 | if (flag && (x = test3_aux()) == 0) { |
56 | x = 1; |
57 | } |
58 | return x; // expected-warning{{variable 'x' is uninitialized when used here}} |
59 | } |
60 | |
61 | enum test4_A { |
62 | test4_A_a, test_4_A_b |
63 | }; |
64 | test4_A test4() { |
65 | test4_A a; // expected-note{{variable 'a' is declared here}} |
66 | return a; // expected-warning{{variable 'a' is uninitialized when used here}} |
67 | } |
68 | |
69 | // Test variables getting invalidated by function calls with reference arguments |
70 | // *AND* there are multiple invalidated arguments. |
71 | void test5_aux(int &, int &); |
72 | |
73 | int test5() { |
74 | int x, y; |
75 | test5_aux(x, y); |
76 | return x + y; // no-warning |
77 | } |
78 | |
79 | // This test previously crashed Sema. |
80 | class Rdar9188004A { |
81 | public: |
82 | virtual ~Rdar9188004A(); |
83 | }; |
84 | |
85 | template< typename T > class Rdar9188004B : public Rdar9188004A { |
86 | virtual double *foo(Rdar9188004B *next) const { |
87 | double *values = next->foo(0); |
88 | try { |
89 | } |
90 | catch(double e) { |
91 | values[0] = e; |
92 | } |
93 | return 0; |
94 | } |
95 | }; |
96 | class Rdar9188004C : public Rdar9188004B<Rdar9188004A> { |
97 | virtual void bar(void) const; |
98 | }; |
99 | void Rdar9188004C::bar(void) const {} |
100 | |
101 | // Don't warn about uninitialized variables in unreachable code. |
102 | void PR9625() { |
103 | if (false) { |
104 | int x; |
105 | (void)static_cast<float>(x); // no-warning |
106 | } |
107 | } |
108 | |
109 | // Don't warn about variables declared in "catch" |
110 | void RDar9251392_bar(const char *msg); |
111 | |
112 | void RDar9251392() { |
113 | try { |
114 | throw "hi"; |
115 | } |
116 | catch (const char* msg) { |
117 | RDar9251392_bar(msg); // no-warning |
118 | } |
119 | } |
120 | |
121 | // Test handling of "no-op" casts. |
122 | void test_noop_cast() |
123 | { |
124 | int x = 1; |
125 | int y = (int&)x; // no-warning |
126 | } |
127 | |
128 | void test_noop_cast2() { |
129 | int x; // expected-note {{initialize the variable 'x' to silence this warning}} |
130 | int y = (int&)x; // expected-warning {{uninitialized when used here}} |
131 | } |
132 | |
133 | // Test handling of bit casts. |
134 | void test_bitcasts() { |
135 | int x = 1; |
136 | int y = (float &)x; // no-warning |
137 | } |
138 | |
139 | void test_bitcasts_2() { |
140 | int x; // expected-note {{initialize the variable 'x' to silence this warning}} |
141 | int y = (float &)x; // expected-warning {{uninitialized when used here}} |
142 | } |
143 | |
144 | void consume_const_ref(const int &n); |
145 | int test_const_ref() { |
146 | int n; // expected-note {{variable}} |
147 | consume_const_ref(n); |
148 | return n; // expected-warning {{uninitialized when used here}} |
149 | } |
150 | |
151 | // Don't crash here. |
152 | auto PR19996 = [a=0]{int t; return a;}; |
153 | |