mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-14 14:56:47 +00:00
[-Wunreachable-code] add a specialized diagnostic for unreachable increment expressions of loops.
llvm-svn: 204430
This commit is contained in:
parent
7f2f9f402c
commit
1421037ece
@ -41,6 +41,7 @@ namespace reachable_code {
|
||||
enum UnreachableKind {
|
||||
UK_Return,
|
||||
UK_Break,
|
||||
UK_Loop_Increment,
|
||||
UK_Other
|
||||
};
|
||||
|
||||
|
@ -430,7 +430,9 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
|
||||
// least actively used, with more noisy versions of the warning covered
|
||||
// under separate flags.
|
||||
//
|
||||
def UnreachableCode : DiagGroup<"unreachable-code">;
|
||||
def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
|
||||
def UnreachableCode : DiagGroup<"unreachable-code",
|
||||
[UnreachableCodeLoopIncrement]>;
|
||||
def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
|
||||
def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
|
||||
def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
|
||||
|
@ -370,6 +370,9 @@ def warn_unreachable_break : Warning<
|
||||
def warn_unreachable_return : Warning<
|
||||
"'return' will never be executed">,
|
||||
InGroup<UnreachableCodeReturn>, DefaultIgnore;
|
||||
def warn_unreachable_loop_increment : Warning<
|
||||
"loop will run at most once (loop increment never executed)">,
|
||||
InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
|
||||
|
||||
/// Built-in functions.
|
||||
def ext_implicit_lib_function_decl : ExtWarn<
|
||||
|
@ -529,6 +529,26 @@ void DeadCodeScan::reportDeadCode(const CFGBlock *B,
|
||||
UK = reachable_code::UK_Return;
|
||||
}
|
||||
|
||||
if (UK == reachable_code::UK_Other) {
|
||||
// Check if the dead code is part of the "loop target" of
|
||||
// a for/for-range loop. This is the block that contains
|
||||
// the increment code.
|
||||
if (const Stmt *LoopTarget = B->getLoopTarget()) {
|
||||
SourceLocation Loc = LoopTarget->getLocStart();
|
||||
SourceRange R1(Loc, Loc), R2;
|
||||
|
||||
if (const ForStmt *FS = dyn_cast<ForStmt>(LoopTarget)) {
|
||||
const Expr *Inc = FS->getInc();
|
||||
Loc = Inc->getLocStart();
|
||||
R2 = Inc->getSourceRange();
|
||||
}
|
||||
|
||||
CB.HandleUnreachable(reachable_code::UK_Loop_Increment,
|
||||
Loc, SourceRange(Loc, Loc), R2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SourceRange R1, R2;
|
||||
SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
|
||||
CB.HandleUnreachable(UK, Loc, R1, R2);
|
||||
|
@ -76,6 +76,9 @@ namespace {
|
||||
case reachable_code::UK_Return:
|
||||
diag = diag::warn_unreachable_return;
|
||||
break;
|
||||
case reachable_code::UK_Loop_Increment:
|
||||
diag = diag::warn_unreachable_loop_increment;
|
||||
break;
|
||||
case reachable_code::UK_Other:
|
||||
break;
|
||||
}
|
||||
@ -1688,7 +1691,8 @@ clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
|
||||
DefaultPolicy.enableCheckUnreachable =
|
||||
isEnabled(D, warn_unreachable) ||
|
||||
isEnabled(D, warn_unreachable_break) ||
|
||||
isEnabled(D, warn_unreachable_return);
|
||||
isEnabled(D, warn_unreachable_return) ||
|
||||
isEnabled(D, warn_unreachable_loop_increment);
|
||||
|
||||
DefaultPolicy.enableThreadSafetyAnalysis =
|
||||
isEnabled(D, warn_double_lock);
|
||||
|
@ -5,7 +5,7 @@ int bar();
|
||||
int test1() {
|
||||
for (int i = 0;
|
||||
i != 10;
|
||||
++i) { // expected-warning {{will never be executed}}
|
||||
++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
|
||||
if (j == 23) // missing {}'s
|
||||
bar();
|
||||
return 1;
|
||||
@ -17,7 +17,7 @@ int test1() {
|
||||
int test1_B() {
|
||||
for (int i = 0;
|
||||
i != 10;
|
||||
++i) { // expected-warning {{will never be executed}}
|
||||
++i) { // expected-warning {{loop will run at most once (loop increment never executed)}}
|
||||
if (j == 23) // missing {}'s
|
||||
bar();
|
||||
return 1;
|
||||
|
@ -282,3 +282,15 @@ void test_static_class_var(Frodo &F) {
|
||||
somethingToCall(); // no-warning
|
||||
}
|
||||
|
||||
void test_unreachable_for_null_increment() {
|
||||
for (unsigned i = 0; i < 10 ; ) // no-warning
|
||||
break;
|
||||
}
|
||||
|
||||
void test_unreachable_forrange_increment() {
|
||||
int x[10] = { 0 };
|
||||
for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,3 +40,12 @@ int test_CONFIG() {
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: This should at some point report a warning
|
||||
// that the loop increment is unreachable.
|
||||
void test_loop_increment(id container) {
|
||||
for (id x in container) { // no-warning
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user