blob: b08467ab51e63dc08e611eb2adb4568766bfd0a0 [file] [log] [blame]
Richard Trieuf935b562014-04-05 05:17:01 +00001// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value -Wno-tautological-compare
Mike Stump04c68512010-01-21 15:20:48 +00002
Anders Carlssonaf7534f2010-09-03 00:25:02 +00003int &halt() __attribute__((noreturn));
Mike Stumpcc3a8532010-01-21 17:21:23 +00004int &live();
Mike Stump04c68512010-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 Stumpcc3a8532010-01-21 17:21:23 +000037
38
39void test3() {
40 halt()
41 --; // expected-warning {{will never be executed}}
Ted Kremenekf8e4b482010-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 Stumpc18c4032010-01-21 19:44:04 +000046 dead() : dead();
Mike Stumpfcd6f942010-01-21 22:12:18 +000047 live(),
Ted Kremenek9e100ea2011-07-19 14:18:48 +000048 float
49 (halt()); // expected-warning {{will never be executed}}
Mike Stumpcc3a8532010-01-21 17:21:23 +000050}
Mike Stump60dbeeb2010-01-21 23:15:53 +000051
52void test4() {
53 struct S {
54 int mem;
55 } s;
56 S &foor();
Zhongxing Xua396e612010-02-24 02:19:28 +000057 halt(), foor()// expected-warning {{will never be executed}}
58 .mem;
Mike Stump60dbeeb2010-01-21 23:15:53 +000059}
60
61void test5() {
62 struct S {
63 int mem;
64 } s;
Richard Smith541b38b2013-09-20 01:15:31 +000065 S &foonr() __attribute__((noreturn));
66 foonr()
Mike Stump60dbeeb2010-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 Kremenek9e100ea2011-07-19 14:18:48 +000076 S
77 (halt()); // expected-warning {{will never be executed}}
Mike Stump60dbeeb2010-01-21 23:15:53 +000078}
Ted Kremenek7f770032011-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 Kremenek85825ae2011-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 Blaikie13ab2a42012-01-24 04:29:27 +0000109
Ted Kremenekeb862842014-03-04 21:41:38 +0000110// 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
Ted Kremenekec2dc732014-03-06 06:50:46 +0000132__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();
Ted Kremenekad8753c2014-03-15 05:47:06 +0000145 return ""; // expected-warning {{'return' will never be executed}}
Ted Kremenekec2dc732014-03-06 06:50:46 +0000146}
147
148std::string testStrWarn(const char *s) {
149 raze();
150 return s; // expected-warning {{will never be executed}}
151}
152
Ted Kremenekc10830b2014-03-07 02:25:50 +0000153bool testBool() {
154 raze();
Ted Kremenekad8753c2014-03-15 05:47:06 +0000155 return true; // expected-warning {{'return' will never be executed}}
Ted Kremenekc10830b2014-03-07 02:25:50 +0000156}
Ted Kremenekeb862842014-03-04 21:41:38 +0000157
Ted Kremenek94d16172014-03-07 20:51:13 +0000158static const bool ConditionVar = 1;
159int test_global_as_conditionVariable() {
160 if (ConditionVar)
161 return 1;
162 return 0; // no-warning
163}
164
Ted Kremenekefea6342014-03-08 02:22:32 +0000165// 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}
Ted Kremenekc980afc2014-03-08 23:20:11 +0000178
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
Ted Kremenek9dfe4002014-03-15 06:47:45 +0000202int 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
Ted Kremenekd4576312014-03-20 18:47:53 +0000221void 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
Ted Kremenekf3c93bb2014-03-20 06:07:30 +0000229class 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
Ted Kremenek2766ad22014-03-20 06:07:35 +0000245void somethingToCall();
246
Ted Kremenekf5ae0bc2014-03-20 06:44:35 +0000247static constexpr bool isConstExprConfigValue() { return true; }
248
249int test_const_expr_config_value() {
250 if (isConstExprConfigValue()) {
Ted Kremenek2766ad22014-03-20 06:07:35 +0000251 somethingToCall();
Ted Kremenekf5ae0bc2014-03-20 06:44:35 +0000252 return 0;
Ted Kremenek2766ad22014-03-20 06:07:35 +0000253 }
Ted Kremenekf5ae0bc2014-03-20 06:44:35 +0000254 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}
Ted Kremenek2766ad22014-03-20 06:07:35 +0000284
Ted Kremenek14210372014-03-21 06:02:36 +0000285void 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
Ted Kremenekab57a152014-03-29 04:49:20 +0000297void 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
Ted Kremenek6f375e52014-04-16 07:26:09 +0000330void 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
Richard Trieuf935b562014-04-05 05:17:01 +0000360void 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}