From: Ted Kremenek Date: Fri, 21 Mar 2014 06:02:36 +0000 (+0000) Subject: [-Wunreachable-code] add a specialized diagnostic for unreachable increment expressio... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62116771bfdb4a5b9830709902fbf8e24ee70eb1;p=clang [-Wunreachable-code] add a specialized diagnostic for unreachable increment expressions of loops. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204430 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h index ed0d711aef..a328ea2c8f 100644 --- a/include/clang/Analysis/Analyses/ReachableCode.h +++ b/include/clang/Analysis/Analyses/ReachableCode.h @@ -41,6 +41,7 @@ namespace reachable_code { enum UnreachableKind { UK_Return, UK_Break, + UK_Loop_Increment, UK_Other }; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c7ea65fac7..8066ed5a3e 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -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", diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7bc66be895..5e45930512 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -370,6 +370,9 @@ def warn_unreachable_break : Warning< def warn_unreachable_return : Warning< "'return' will never be executed">, InGroup, DefaultIgnore; +def warn_unreachable_loop_increment : Warning< + "loop will run at most once (loop increment never executed)">, + InGroup, DefaultIgnore; /// Built-in functions. def ext_implicit_lib_function_decl : ExtWarn< diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index 4220000cd3..53e03de64e 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -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(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); diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 389109a11b..ecf6d51ef1 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -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); diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp index 5016c3f24b..fd006c099e 100644 --- a/test/SemaCXX/unreachable-code.cpp +++ b/test/SemaCXX/unreachable-code.cpp @@ -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; diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp index eab8d8e6b9..8acaf42855 100644 --- a/test/SemaCXX/warn-unreachable.cpp +++ b/test/SemaCXX/warn-unreachable.cpp @@ -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; + } +} + diff --git a/test/SemaObjC/warn-unreachable.m b/test/SemaObjC/warn-unreachable.m index 979b9053b3..859bd00f31 100644 --- a/test/SemaObjC/warn-unreachable.m +++ b/test/SemaObjC/warn-unreachable.m @@ -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; + } +} +