llvm-project/clang/test/Sema/warn-unreachable.c
Aaron Ballman 0f1c1be196 [clang] Remove rdar links; NFC
We have a new policy in place making links to private resources
something we try to avoid in source and test files. Normally, we'd
organically switch to the new policy rather than make a sweeping change
across a project. However, Clang is in a somewhat special circumstance
currently: recently, I've had several new contributors run into rdar
links around test code which their patch was changing the behavior of.
This turns out to be a surprisingly bad experience, especially for
newer folks, for a handful of reasons: not understanding what the link
is and feeling intimidated by it, wondering whether their changes are
actually breaking something important to a downstream in some way,
having to hunt down strangers not involved with the patch to impose on
them for help, accidental pressure from asking for potentially private
IP to be made public, etc. Because folks run into these links entirely
by chance (through fixing bugs or working on new features), there's not
really a set of problematic links to focus on -- all of the links have
basically the same potential for causing these problems. As a result,
this is an omnibus patch to remove all such links.

This was not a mechanical change; it was done by manually searching for
rdar, radar, radr, and other variants to find all the various
problematic links. From there, I tried to retain or reword the
surrounding comments so that we would lose as little context as
possible. However, because most links were just a plain link with no
supporting context, the majority of the changes are simple removals.

Differential Review: https://reviews.llvm.org/D158071
2023-08-28 12:13:42 -04:00

502 lines
13 KiB
C

// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs %s
// 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 %s
#include "warn-unreachable.h"
int halt(void) __attribute__((noreturn));
int live(void);
int dead(void);
void test1(void) {
goto c;
d:
goto e; // expected-warning {{will never be executed}}
c: ;
int i;
return;
goto b; // expected-warning {{will never be executed}}
goto a; // expected-warning {{will never be executed}}
b:
i = 1;
a:
i = 2;
goto f;
e:
goto d;
f: ;
}
void test2(void) {
int i;
switch (live()) {
case 1:
halt(),
dead(); // expected-warning {{will never be executed}}
case 2:
live(), halt(),
dead(); // expected-warning {{will never be executed}}
case 3:
live()
+ // expected-warning {{will never be executed}}
halt();
dead();
case 4:
a4:
live(),
halt();
goto a4; // expected-warning {{will never be executed}}
case 5:
goto a5;
c5:
dead(); // expected-warning {{will never be executed}}
goto b5;
a5:
live(),
halt();
b5:
goto c5;
case 6:
if (live())
goto e6;
live(),
halt();
d6:
dead(); // expected-warning {{will never be executed}}
goto b6;
c6:
dead();
goto b6;
e6:
live(),
halt();
b6:
goto c6;
case 7:
halt()
+
dead(); // expected-warning {{will never be executed}}
- // expected-warning {{will never be executed}}
halt();
case 8:
i
+= // expected-warning {{will never be executed}}
halt();
case 9:
halt()
? // expected-warning {{will never be executed}}
dead() : dead();
case 10:
( // expected-warning {{will never be executed}}
float)halt();
case 11: {
int a[5];
live(),
a[halt()
]; // expected-warning {{will never be executed}}
}
}
}
enum Cases { C1, C2, C3 };
int test_enum_cases(enum Cases C) {
switch (C) {
case C1:
case C2:
case C3:
return 1;
default: {
int i = 0; // no-warning
++i;
return i;
}
}
}
// Handle unreachable code triggered by macro expansions.
void __myassert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
#define myassert(e) \
(__builtin_expect(!(e), 0) ? __myassert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
void test_assert(void) {
myassert(0 && "unreachable");
return; // no-warning
}
// Test case for PR 9774. Tests that dead code in macros aren't warned about.
#define MY_MAX(a,b) ((a) >= (b) ? (a) : (b))
void PR9774(int *s) {
for (int i = 0; i < MY_MAX(2, 3); i++) // no-warning
s[i] = 0;
}
// We should treat code guarded by 'x & 0' and 'x * 0' as unreachable.
int calledFun(void);
void test_mul_and_zero(int x) {
if (x & 0) calledFun(); // expected-warning {{will never be executed}}
if (0 & x) calledFun(); // expected-warning {{will never be executed}}
if (x * 0) calledFun(); // expected-warning {{will never be executed}}
if (0 * x) calledFun(); // expected-warning {{will never be executed}}
}
void raze(void) __attribute__((noreturn));
void warn_here(void);
int test_break_preceded_by_noreturn(int i) {
switch (i) {
case 1:
raze();
break; // expected-warning {{'break' will never be executed}}
case 2:
raze();
break; // expected-warning {{'break' will never be executed}}
warn_here(); // expected-warning {{will never be executed}}
case 3:
return 1;
break; // expected-warning {{will never be executed}}
default:
break;
break; // expected-warning {{will never be executed}}
}
return i;
}
// Don't warn about unreachable 'default' cases, as that is covered
// by -Wcovered-switch-default.
typedef enum { Value1 = 1 } MyEnum;
void unreachable_default(MyEnum e) {
switch (e) {
case Value1:
calledFun();
break;
case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}}
calledFun();
break;
default:
calledFun(); // no-warning
break;
}
}
void unreachable_in_default(MyEnum e) {
switch (e) {
default:
raze();
calledFun(); // expected-warning {{will never be executed}}
break;
}
}
// Don't warn about trivial dead returns.
int trivial_dead_return(void) {
raze();
return ((0)); // expected-warning {{'return' will never be executed}}
}
void trivial_dead_return_void(void) {
raze();
return; // expected-warning {{'return' will never be executed}}
}
MyEnum trivial_dead_return_enum(void) {
raze();
return Value1; // expected-warning {{'return' will never be executed}}
}
MyEnum trivial_dead_return_enum_2(int x) {
switch (x) {
case 1: return 1;
case 2: return 2;
case 3: return 3;
default: return 4;
}
return 2; // expected-warning {{will never be executed}}
}
const char *trivial_dead_return_cstr(void) {
raze();
return ""; // expected-warning {{return' will never be executed}}
}
char trivial_dead_return_char(void) {
raze();
return ' '; // expected-warning {{return' will never be executed}}
}
MyEnum nontrivial_dead_return_enum_2(int x) {
switch (x) {
case 1: return 1;
case 2: return 2;
case 3: return 3;
default: return 4;
}
return calledFun(); // expected-warning {{will never be executed}}
}
enum X { A, B, C };
int covered_switch(enum X x) {
switch (x) {
case A: return 1;
case B: return 2;
case C: return 3;
}
return 4; // no-warning
}
// Test unreachable code depending on configuration values
#define CONFIG_CONSTANT 1
int test_config_constant(int x) {
if (!CONFIG_CONSTANT) {
calledFun(); // no-warning
return 1;
}
if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun(); // expected-warning {{will never be executed}}
return 1;
}
if (sizeof(int) > sizeof(char)) {
calledFun(); // no-warning
return 1;
}
if (x > 10)
return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning
else
return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun() :
calledFun(); // expected-warning {{will never be executed}}
}
int sizeof_int(int x, int y) {
if (sizeof(long) == sizeof(int))
return 1; // no-warning
if (sizeof(long) != sizeof(int))
return 0; // no-warning
if (x && y && sizeof(long) < sizeof(char))
return 0; // no-warning
return 2; // no-warning
}
enum MyEnum2 {
ME_A = CONFIG_CONSTANT,
ME_B = 1
};
int test_MyEnum(void) {
if (!ME_A)
return 1; // no-warning
if (ME_A)
return 2; // no-warning
if (ME_B)
return 3;
if (!ME_B) // expected-warning {{will never be executed}}
return 4; // expected-warning {{will never be executed}}
return 5;
}
// Test for idiomatic do..while.
int test_do_while(int x) {
do {
if (x == calledFun())
break;
++x;
break;
}
while (0); // no-warning
return x;
}
int test_do_while_nontrivial_cond(int x) {
do {
if (x == calledFun())
break;
++x;
break;
}
while (calledFun()); // expected-warning {{will never be executed}}
return x;
}
// Diagnostic control: -Wunreachable-code-return.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code-return"
void trivial_dead_return_void_SUPPRESSED(void) {
raze();
return; // no-warning
}
MyEnum trivial_dead_return_enum_SUPPRESSED(void) {
raze();
return Value1; // no-warning
}
#pragma clang diagnostic pop
// Diagnostic control: -Wunreachable-code-break.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code-break"
int test_break_preceded_by_noreturn_SUPPRESSED(int i) {
switch (i) {
case 1:
raze();
break; // no-warning
case 2:
raze();
break; // no-warning
warn_here(); // expected-warning {{will never be executed}}
case 3:
return 1;
break; // no-warning
default:
break;
break; // no-warning
}
return i;
}
#pragma clang diagnostic pop
// Test "silencing" with parentheses.
void test_with_paren_silencing(int x) {
if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
if ((0)) calledFun(); // no-warning
if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun();
else
calledFun(); // expected-warning {{will never be executed}}
if ((1))
calledFun();
else
calledFun(); // no-warning
if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
calledFun(); // expected-warning {{code will never be executed}}
else
calledFun();
if ((!1))
calledFun(); // no-warning
else
calledFun();
if (!(1))
calledFun(); // no-warning
else
calledFun();
}
struct StructWithPointer {
void *p;
};
void emitJustOneWarningForOr(struct StructWithPointer *s) {
if (1 || !s->p) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:8-[[@LINE-2]]:8}:")"
emitJustOneWarningForOr(s); // expected-warning {{code will never be executed}}
}
void emitJustOneWarningForOrSilenced(struct StructWithPointer *s) {
if ((1) || !s->p)
return;
emitJustOneWarningForOrSilenced(s); // no warning
}
void emitJustOneWarningForOr2(struct StructWithPointer *s) {
if (1 || !s->p) // expected-warning {{code will never be executed}}
return; // expected-note@-1 {{silence by adding parentheses to mark code as explicitly dead}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:7}:"/* DISABLES CODE */ ("
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:8-[[@LINE-3]]:8}:")"
}
void wrapOneInFixit(struct StructWithPointer *s) {
if (!s->p || 1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"/* DISABLES CODE */ ("
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:")"
wrapOneInFixit(s); // expected-warning {{code will never be executed}}
}
void unaryOpNoFixit(void) {
if (~ 1)
return; // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]
unaryOpNoFixit(); // expected-warning {{code will never be executed}}
}
void unaryOpStrictFixit(struct StructWithPointer *s) {
if (!(s->p && 0)) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"/* DISABLES CODE */ ("
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:18-[[@LINE-2]]:18}:")"
unaryOpStrictFixit(s); // expected-warning {{code will never be executed}}
}
void unaryOpFixitCastSubExpr(int x) {
if (! (int)0) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
return; // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:7-[[@LINE-1]]:7}:"/* DISABLES CODE */ ("
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"
unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}
}
#define false 0
#define true 1
void testTrueFalseMacros(void) {
if (false) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
testTrueFalseMacros(); // expected-warning {{code will never be executed}}
if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
testTrueFalseMacros(); // expected-warning {{code will never be executed}}
}
int pr13910_foo(int x) {
if (x == 1)
return 0;
else
return x;
__builtin_unreachable(); // expected no warning
__builtin_assume(0); // expected no warning
}
int pr13910_bar(int x) {
switch (x) {
default:
return x + 1;
}
pr13910_foo(x); // expected-warning {{code will never be executed}}
}
int pr13910_bar2(int x) {
if (x == 1)
return 0;
else
return x;
pr13910_foo(x); // expected-warning {{code will never be executed}}
__builtin_unreachable(); // expected no warning
__builtin_assume(0); // expected no warning
pr13910_foo(x); // expected-warning {{code will never be executed}}
}
void pr13910_noreturn(void) {
raze();
__builtin_unreachable(); // expected no warning
__builtin_assume(0); // expected no warning
}
void pr13910_assert(void) {
myassert(0 && "unreachable");
return;
__builtin_unreachable(); // expected no warning
__builtin_assume(0); // expected no warning
}