blob: b08467ab51e63dc08e611eb2adb4568766bfd0a0 [file] [log] [blame]
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value -Wno-tautological-compare
Mike Stump4c45aa12010-01-21 15:20:48 +00002
Anders Carlsson5d1d7ae2010-09-03 00:25:02 +00003int &halt() __attribute__((noreturn));
Mike Stump55f988e2010-01-21 17:21:23 +00004int &live();
Mike Stump4c45aa12010-01-21 15:20:48 +00005int dead();
6int liveti() throw(int);
7int (*livetip)() throw(int);
8
9int test1() {
10 try {
11 live();
12 } catch (int i) {
13 live();
14 }
15 return 1;
16}
17
18void test2() {
19 try {
20 live();
21 } catch (int i) {
22 live();
23 }
24 try {
25 liveti();
26 } catch (int i) {
27 live();
28 }
29 try {
30 livetip();
31 } catch (int i) {
32 live();
33 }
34 throw 1;
35 dead(); // expected-warning {{will never be executed}}
36}
Mike Stump55f988e2010-01-21 17:21:23 +000037
38
39void test3() {
40 halt()
41 --; // expected-warning {{will never be executed}}
Ted Kremenek7dd3c732010-12-16 08:22:16 +000042 // FIXME: The unreachable part is just the '?', but really all of this
43 // code is unreachable and shouldn't be separately reported.
44 halt() // expected-warning {{will never be executed}}
45 ?
Mike Stumpe5fba702010-01-21 19:44:04 +000046 dead() : dead();
Mike Stump2d6ceab2010-01-21 22:12:18 +000047 live(),
Ted Kremenek0c8e5a02011-07-19 14:18:48 +000048 float
49 (halt()); // expected-warning {{will never be executed}}
Mike Stump55f988e2010-01-21 17:21:23 +000050}
Mike Stumpb5c77552010-01-21 23:15:53 +000051
52void test4() {
53 struct S {
54 int mem;
55 } s;
56 S &foor();
Zhongxing Xu91071662010-02-24 02:19:28 +000057 halt(), foor()// expected-warning {{will never be executed}}
58 .mem;
Mike Stumpb5c77552010-01-21 23:15:53 +000059}
60
61void test5() {
62 struct S {
63 int mem;
64 } s;
Richard Smitha41c97a2013-09-20 01:15:31 +000065 S &foonr() __attribute__((noreturn));
66 foonr()
Mike Stumpb5c77552010-01-21 23:15:53 +000067 .mem; // expected-warning {{will never be executed}}
68}
69
70void test6() {
71 struct S {
72 ~S() { }
73 S(int i) { }
74 };
75 live(),
Ted Kremenek0c8e5a02011-07-19 14:18:48 +000076 S
77 (halt()); // expected-warning {{will never be executed}}
Mike Stumpb5c77552010-01-21 23:15:53 +000078}
Ted Kremenek5dfee062011-11-30 21:22:09 +000079
80// Don't warn about unreachable code in template instantiations, as
81// they may only be unreachable in that specific instantiation.
82void isUnreachable();
83
84template <typename T> void test_unreachable_templates() {
85 T::foo();
86 isUnreachable(); // no-warning
87}
88
89struct TestUnreachableA {
90 static void foo() __attribute__((noreturn));
91};
92struct TestUnreachableB {
93 static void foo();
94};
95
96void test_unreachable_templates_harness() {
97 test_unreachable_templates<TestUnreachableA>();
98 test_unreachable_templates<TestUnreachableB>();
99}
100
Ted Kremenek75df4ee2011-12-01 00:59:17 +0000101// Do warn about explict template specializations, as they represent
102// actual concrete functions that somebody wrote.
103
104template <typename T> void funcToSpecialize() {}
105template <> void funcToSpecialize<int>() {
106 halt();
107 dead(); // expected-warning {{will never be executed}}
108}
David Blaikie25f4c192012-01-24 04:29:27 +0000109
Stephen Hines651f13c2014-04-23 16:59:28 -0700110// Handle 'try' code dominating a dead return.
111enum PR19040_test_return_t
112{ PR19040_TEST_FAILURE };
113namespace PR19040_libtest
114{
115 class A {
116 public:
117 ~A ();
118 };
119}
120PR19040_test_return_t PR19040_fn1 ()
121{
122 try
123 {
124 throw PR19040_libtest::A ();
125 } catch (...)
126 {
127 return PR19040_TEST_FAILURE;
128 }
129 return PR19040_TEST_FAILURE; // expected-warning {{will never be executed}}
130}
131
132__attribute__((noreturn))
133void raze();
134
135namespace std {
136template<typename T> struct basic_string {
137 basic_string(const T* x) {}
138 ~basic_string() {};
139};
140typedef basic_string<char> string;
141}
142
143std::string testStr() {
144 raze();
145 return ""; // expected-warning {{'return' will never be executed}}
146}
147
148std::string testStrWarn(const char *s) {
149 raze();
150 return s; // expected-warning {{will never be executed}}
151}
152
153bool testBool() {
154 raze();
155 return true; // expected-warning {{'return' will never be executed}}
156}
157
158static const bool ConditionVar = 1;
159int test_global_as_conditionVariable() {
160 if (ConditionVar)
161 return 1;
162 return 0; // no-warning
163}
164
165// Handle unreachable temporary destructors.
166class A {
167public:
168 A();
169 ~A();
170};
171
172__attribute__((noreturn))
173void raze(const A& x);
174
175void test_with_unreachable_tmp_dtors(int x) {
176 raze(x ? A() : A()); // no-warning
177}
178
179// Test sizeof - sizeof in enum declaration.
180enum { BrownCow = sizeof(long) - sizeof(char) };
181enum { CowBrown = 8 - 1 };
182
183
184int test_enum_sizeof_arithmetic() {
185 if (BrownCow)
186 return 1;
187 return 2;
188}
189
190int test_enum_arithmetic() {
191 if (CowBrown)
192 return 1;
193 return 2; // expected-warning {{never be executed}}
194}
195
196int test_arithmetic() {
197 if (8 -1)
198 return 1;
199 return 2; // expected-warning {{never be executed}}
200}
201
202int test_treat_const_bool_local_as_config_value() {
203 const bool controlValue = false;
204 if (!controlValue)
205 return 1;
206 test_treat_const_bool_local_as_config_value(); // no-warning
207 return 0;
208}
209
210int test_treat_non_const_bool_local_as_non_config_value() {
211 bool controlValue = false;
212 if (!controlValue)
213 return 1;
214 // There is no warning here because 'controlValue' isn't really
215 // a control value at all. The CFG will not treat this
216 // branch as unreachable.
217 test_treat_non_const_bool_local_as_non_config_value(); // no-warning
218 return 0;
219}
220
221void test_do_while(int x) {
222 // Handle trivial expressions with
223 // implicit casts to bool.
224 do {
225 break;
226 } while (0); // no-warning
227}
228
229class Frobozz {
230public:
231 Frobozz(int x);
232 ~Frobozz();
233};
234
235Frobozz test_return_object(int flag) {
236 return Frobozz(flag);
237 return Frobozz(42); // expected-warning {{'return' will never be executed}}
238}
239
240Frobozz test_return_object_control_flow(int flag) {
241 return Frobozz(flag);
242 return Frobozz(flag ? 42 : 24); // expected-warning {{code will never be executed}}
243}
244
245void somethingToCall();
246
247static constexpr bool isConstExprConfigValue() { return true; }
248
249int test_const_expr_config_value() {
250 if (isConstExprConfigValue()) {
251 somethingToCall();
252 return 0;
253 }
254 somethingToCall(); // no-warning
255 return 1;
256}
257int test_const_expr_config_value_2() {
258 if (!isConstExprConfigValue()) {
259 somethingToCall(); // no-warning
260 return 0;
261 }
262 somethingToCall();
263 return 1;
264}
265
266class Frodo {
267public:
268 static const bool aHobbit = true;
269};
270
271void test_static_class_var() {
272 if (Frodo::aHobbit)
273 somethingToCall();
274 else
275 somethingToCall(); // no-warning
276}
277
278void test_static_class_var(Frodo &F) {
279 if (F.aHobbit)
280 somethingToCall();
281 else
282 somethingToCall(); // no-warning
283}
284
285void test_unreachable_for_null_increment() {
286 for (unsigned i = 0; i < 10 ; ) // no-warning
287 break;
288}
289
290void test_unreachable_forrange_increment() {
291 int x[10] = { 0 };
292 for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
293 break;
294 }
295}
296
297void calledFun() {}
298
299// Test "silencing" with parentheses.
300void test_with_paren_silencing(int x) {
301 if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
302 if ((false)) calledFun(); // no-warning
303
304 if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
305 calledFun();
306 else
307 calledFun(); // expected-warning {{will never be executed}}
308
309 if ((true))
310 calledFun();
311 else
312 calledFun(); // no-warning
313
314 if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
315 calledFun(); // expected-warning {{code will never be executed}}
316 else
317 calledFun();
318
319 if ((!true))
320 calledFun(); // no-warning
321 else
322 calledFun();
323
324 if (!(true))
325 calledFun(); // no-warning
326 else
327 calledFun();
328}
329
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700330void test_with_paren_silencing_impcast(int x) {
331 if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
332 if ((0)) calledFun(); // no-warning
333
334 if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
335 calledFun();
336 else
337 calledFun(); // expected-warning {{will never be executed}}
338
339 if ((1))
340 calledFun();
341 else
342 calledFun(); // no-warning
343
344 if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
345 calledFun(); // expected-warning {{code will never be executed}}
346 else
347 calledFun();
348
349 if ((!1))
350 calledFun(); // no-warning
351 else
352 calledFun();
353
354 if (!(1))
355 calledFun(); // no-warning
356 else
357 calledFun();
358}
359
360void tautological_compare(bool x, int y) {
361 if (x > 10) // expected-note {{silence}}
362 calledFun(); // expected-warning {{will never be executed}}
363 if (10 < x) // expected-note {{silence}}
364 calledFun(); // expected-warning {{will never be executed}}
365 if (x == 10) // expected-note {{silence}}
366 calledFun(); // expected-warning {{will never be executed}}
367
368 if (x < 10) // expected-note {{silence}}
369 calledFun();
370 else
371 calledFun(); // expected-warning {{will never be executed}}
372 if (10 > x) // expected-note {{silence}}
373 calledFun();
374 else
375 calledFun(); // expected-warning {{will never be executed}}
376 if (x != 10) // expected-note {{silence}}
377 calledFun();
378 else
379 calledFun(); // expected-warning {{will never be executed}}
380
381 if (y != 5 && y == 5) // expected-note {{silence}}
382 calledFun(); // expected-warning {{will never be executed}}
383
384 if (y > 5 && y < 4) // expected-note {{silence}}
385 calledFun(); // expected-warning {{will never be executed}}
386
387 if (y < 10 || y > 5) // expected-note {{silence}}
388 calledFun();
389 else
390 calledFun(); // expected-warning {{will never be executed}}
391
392 // TODO: Extend warning to the following code:
393 if (x < -1)
394 calledFun();
395 if (x == -1)
396 calledFun();
397
398 if (x != -1)
399 calledFun();
400 else
401 calledFun();
402 if (-1 > x)
403 calledFun();
404 else
405 calledFun();
406
407 if (y == -1 && y != -1)
408 calledFun();
409}