502 lines · c
1// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs %s2// RUN: %clang_cc1 -fsyntax-only -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -fdiagnostics-parseable-fixits -I %S/Inputs %s 2>&1 | FileCheck %s3 4#include "warn-unreachable.h"5 6int halt(void) __attribute__((noreturn));7int live(void);8int dead(void);9 10void test1(void) {11 goto c;12 d:13 goto e; // expected-warning {{will never be executed}}14 c: ;15 int i;16 return;17 goto b; // expected-warning {{will never be executed}}18 goto a; // expected-warning {{will never be executed}}19 b:20 i = 1;21 a:22 i = 2;23 goto f;24 e:25 goto d;26 f: ;27}28 29void test2(void) {30 int i;31 switch (live()) {32 case 1:33 halt(),34 dead(); // expected-warning {{will never be executed}}35 36 case 2:37 live(), halt(),38 dead(); // expected-warning {{will never be executed}}39 40 case 3:41 live()42 + // expected-warning {{will never be executed}}43 halt();44 dead();45 46 case 4:47 a4:48 live(),49 halt();50 goto a4; // expected-warning {{will never be executed}}51 52 case 5:53 goto a5;54 c5:55 dead(); // expected-warning {{will never be executed}}56 goto b5;57 a5:58 live(),59 halt();60 b5:61 goto c5;62 63 case 6:64 if (live())65 goto e6;66 live(),67 halt();68 d6:69 dead(); // expected-warning {{will never be executed}}70 goto b6;71 c6:72 dead();73 goto b6;74 e6:75 live(),76 halt();77 b6:78 goto c6;79 case 7:80 halt()81 +82 dead(); // expected-warning {{will never be executed}}83 - // expected-warning {{will never be executed}}84 halt();85 case 8:86 i87 += // expected-warning {{will never be executed}}88 halt();89 case 9:90 halt()91 ? // expected-warning {{will never be executed}}92 dead() : dead();93 case 10:94 ( // expected-warning {{will never be executed}}95 float)halt();96 case 11: {97 int a[5];98 live(),99 a[halt()100 ]; // expected-warning {{will never be executed}}101 }102 }103}104 105enum Cases { C1, C2, C3 };106int test_enum_cases(enum Cases C) {107 switch (C) {108 case C1:109 case C2:110 case C3:111 return 1;112 default: {113 int i = 0; // no-warning114 ++i;115 return i;116 }117 } 118}119 120// Handle unreachable code triggered by macro expansions.121void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));122 123#define myassert(e) \124 (__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)125 126void test_assert(void) {127 myassert(0 && "unreachable");128 return; // no-warning129}130 131// Test case for PR 9774. Tests that dead code in macros aren't warned about.132#define MY_MAX(a,b) ((a) >= (b) ? (a) : (b))133void PR9774(int *s) {134 for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning135 s[i] = 0;136}137 138// We should treat code guarded by 'x & 0' and 'x * 0' as unreachable.139int calledFun(void);140void test_mul_and_zero(int x) {141 if (x & 0) calledFun(); // expected-warning {{will never be executed}}142 if (0 & x) calledFun(); // expected-warning {{will never be executed}}143 if (x * 0) calledFun(); // expected-warning {{will never be executed}}144 if (0 * x) calledFun(); // expected-warning {{will never be executed}}145}146 147void raze(void) __attribute__((noreturn));148void warn_here(void);149 150int test_break_preceded_by_noreturn(int i) {151 switch (i) {152 case 1:153 raze();154 break; // expected-warning {{'break' will never be executed}}155 case 2:156 raze();157 break; // expected-warning {{'break' will never be executed}}158 warn_here(); // expected-warning {{will never be executed}}159 case 3:160 return 1;161 break; // expected-warning {{will never be executed}}162 default:163 break;164 break; // expected-warning {{will never be executed}}165 }166 return i;167}168 169// Don't warn about unreachable 'default' cases, as that is covered170// by -Wcovered-switch-default.171typedef enum { Value1 = 1 } MyEnum;172void unreachable_default(MyEnum e) {173 switch (e) {174 case Value1:175 calledFun();176 break;177 case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}}178 calledFun();179 break;180 default:181 calledFun(); // no-warning182 break;183 }184}185void unreachable_in_default(MyEnum e) {186 switch (e) {187 default:188 raze();189 calledFun(); // expected-warning {{will never be executed}}190 break;191 }192}193 194// Don't warn about trivial dead returns.195int trivial_dead_return(void) {196 raze();197 return ((0)); // expected-warning {{'return' will never be executed}}198}199 200void trivial_dead_return_void(void) {201 raze();202 return; // expected-warning {{'return' will never be executed}}203}204 205MyEnum trivial_dead_return_enum(void) {206 raze();207 return Value1; // expected-warning {{'return' will never be executed}}208}209 210MyEnum trivial_dead_return_enum_2(int x) {211 switch (x) {212 case 1: return 1;213 case 2: return 2;214 case 3: return 3;215 default: return 4;216 }217 218 return 2; // expected-warning {{will never be executed}}219}220 221const char *trivial_dead_return_cstr(void) {222 raze();223 return ""; // expected-warning {{return' will never be executed}}224}225 226char trivial_dead_return_char(void) {227 raze();228 return ' '; // expected-warning {{return' will never be executed}}229}230 231MyEnum nontrivial_dead_return_enum_2(int x) {232 switch (x) {233 case 1: return 1;234 case 2: return 2;235 case 3: return 3;236 default: return 4;237 }238 239 return calledFun(); // expected-warning {{will never be executed}}240}241 242enum X { A, B, C };243 244int covered_switch(enum X x) {245 switch (x) {246 case A: return 1;247 case B: return 2;248 case C: return 3;249 }250 return 4; // no-warning251}252 253// Test unreachable code depending on configuration values254#define CONFIG_CONSTANT 1255int test_config_constant(int x) {256 if (!CONFIG_CONSTANT) {257 calledFun(); // no-warning258 return 1;259 }260 if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}}261 calledFun(); // expected-warning {{will never be executed}}262 return 1;263 }264 if (sizeof(int) > sizeof(char)) {265 calledFun(); // no-warning266 return 1;267 }268 if (x > 10)269 return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning270 else271 return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}}272 calledFun() :273 calledFun(); // expected-warning {{will never be executed}}274}275 276int sizeof_int(int x, int y) {277 if (sizeof(long) == sizeof(int))278 return 1; // no-warning279 if (sizeof(long) != sizeof(int))280 return 0; // no-warning281 if (x && y && sizeof(long) < sizeof(char))282 return 0; // no-warning283 return 2; // no-warning284}285 286enum MyEnum2 {287 ME_A = CONFIG_CONSTANT,288 ME_B = 1289};290 291int test_MyEnum(void) {292 if (!ME_A)293 return 1; // no-warning294 if (ME_A)295 return 2; // no-warning296 if (ME_B)297 return 3;298 if (!ME_B) // expected-warning {{will never be executed}}299 return 4; // expected-warning {{will never be executed}}300 return 5;301}302 303// Test for idiomatic do..while.304int test_do_while(int x) {305 do {306 if (x == calledFun())307 break;308 ++x;309 break;310 }311 while (0); // no-warning312 return x;313}314 315int test_do_while_nontrivial_cond(int x) {316 do {317 if (x == calledFun())318 break;319 ++x;320 break;321 }322 while (calledFun()); // expected-warning {{will never be executed}}323 return x;324}325 326// Diagnostic control: -Wunreachable-code-return.327 328#pragma clang diagnostic push329#pragma clang diagnostic ignored "-Wunreachable-code-return"330 331void trivial_dead_return_void_SUPPRESSED(void) {332 raze();333 return; // no-warning334}335 336MyEnum trivial_dead_return_enum_SUPPRESSED(void) {337 raze();338 return Value1; // no-warning339}340 341#pragma clang diagnostic pop342 343// Diagnostic control: -Wunreachable-code-break.344 345#pragma clang diagnostic push346#pragma clang diagnostic ignored "-Wunreachable-code-break"347 348int test_break_preceded_by_noreturn_SUPPRESSED(int i) {349 switch (i) {350 case 1:351 raze();352 break; // no-warning353 case 2:354 raze();355 break; // no-warning356 warn_here(); // expected-warning {{will never be executed}}357 case 3:358 return 1;359 break; // no-warning360 default:361 break;362 break; // no-warning363 }364 return i;365}366 367#pragma clang diagnostic pop368 369// Test "silencing" with parentheses.370void test_with_paren_silencing(int x) {371 if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}372 if ((0)) calledFun(); // no-warning373 374 if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}375 calledFun();376 else377 calledFun(); // expected-warning {{will never be executed}}378 379 if ((1))380 calledFun();381 else382 calledFun(); // no-warning383 384 if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}385 calledFun(); // expected-warning {{code will never be executed}}386 else387 calledFun();388 389 if ((!1))390 calledFun(); // no-warning391 else392 calledFun();393 394 if (!(1))395 calledFun(); // no-warning396 else397 calledFun();398}399 400struct StructWithPointer {401 void *p;402};403 404void emitJustOneWarningForOr(struct StructWithPointer *s) {405 if (1 || !s->p) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}406 return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("407 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:8}:")"408 emitJustOneWarningForOr(s); // expected-warning {{code will never be executed}}409}410 411void emitJustOneWarningForOrSilenced(struct StructWithPointer *s) {412 if ((1) || !s->p)413 return;414 415 emitJustOneWarningForOrSilenced(s); // no warning416}417 418void emitJustOneWarningForOr2(struct StructWithPointer *s) {419 if (1 || !s->p) // expected-warning {{code will never be executed}}420 return; // expected-note@-1 {{silence by adding parentheses to mark code as explicitly dead}}421 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:7}:"/* DISABLES CODE */ ("422 // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:")"423}424 425void wrapOneInFixit(struct StructWithPointer *s) {426 if (!s->p || 1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}427 return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"/* DISABLES CODE */ ("428 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:")"429 wrapOneInFixit(s); // expected-warning {{code will never be executed}}430}431 432void unaryOpNoFixit(void) {433 if (~ 1)434 return; // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]435 unaryOpNoFixit(); // expected-warning {{code will never be executed}}436}437 438void unaryOpStrictFixit(struct StructWithPointer *s) {439 if (!(s->p && 0)) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}440 return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"/* DISABLES CODE */ ("441 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:")"442 unaryOpStrictFixit(s); // expected-warning {{code will never be executed}}443}444 445void unaryOpFixitCastSubExpr(int x) {446 if (! (int)0) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}447 return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("448 // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"449 unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}450}451 452#define false 0453#define true 1454 455void testTrueFalseMacros(void) {456 if (false) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}457 testTrueFalseMacros(); // expected-warning {{code will never be executed}}458 if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}459 testTrueFalseMacros(); // expected-warning {{code will never be executed}}460}461 462int pr13910_foo(int x) {463 if (x == 1)464 return 0;465 else466 return x;467 __builtin_unreachable(); // expected no warning468 __builtin_assume(0); // expected no warning469}470 471int pr13910_bar(int x) {472 switch (x) {473 default:474 return x + 1;475 }476 pr13910_foo(x); // expected-warning {{code will never be executed}}477}478 479int pr13910_bar2(int x) {480 if (x == 1)481 return 0;482 else483 return x;484 pr13910_foo(x); // expected-warning {{code will never be executed}}485 __builtin_unreachable(); // expected no warning486 __builtin_assume(0); // expected no warning487 pr13910_foo(x); // expected-warning {{code will never be executed}}488}489 490void pr13910_noreturn(void) {491 raze();492 __builtin_unreachable(); // expected no warning493 __builtin_assume(0); // expected no warning494}495 496void pr13910_assert(void) {497 myassert(0 && "unreachable");498 return;499 __builtin_unreachable(); // expected no warning500 __builtin_assume(0); // expected no warning501}502