diff options
author | Ted Kremenek <kremenek@apple.com> | 2014-03-21 06:02:36 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2014-03-21 06:02:36 +0000 |
commit | 1421037ece1f3f4e20ab5e81b6931557218e9562 (patch) | |
tree | e3861c8a6940d865630c50adaa194f2bf8a13132 | |
parent | 7f2f9f402c0e05843697b2955ad719a27cf2cb99 (diff) | |
download | llvm-1421037ece1f3f4e20ab5e81b6931557218e9562.zip llvm-1421037ece1f3f4e20ab5e81b6931557218e9562.tar.gz llvm-1421037ece1f3f4e20ab5e81b6931557218e9562.tar.bz2 |
[-Wunreachable-code] add a specialized diagnostic for unreachable increment expressions of loops.
llvm-svn: 204430
-rw-r--r-- | clang/include/clang/Analysis/Analyses/ReachableCode.h | 1 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticGroups.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Analysis/ReachableCode.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/unreachable-code.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unreachable.cpp | 12 | ||||
-rw-r--r-- | clang/test/SemaObjC/warn-unreachable.m | 9 |
8 files changed, 55 insertions, 4 deletions
diff --git a/clang/include/clang/Analysis/Analyses/ReachableCode.h b/clang/include/clang/Analysis/Analyses/ReachableCode.h index ed0d711..a328ea2 100644 --- a/clang/include/clang/Analysis/Analyses/ReachableCode.h +++ b/clang/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/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index c7ea65f..8066ed5 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/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/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7bc66be..5e45930 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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<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< diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp index 4220000..53e03de 100644 --- a/clang/lib/Analysis/ReachableCode.cpp +++ b/clang/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<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); diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 389109a..ecf6d51 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/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/clang/test/SemaCXX/unreachable-code.cpp b/clang/test/SemaCXX/unreachable-code.cpp index 5016c3f..fd006c0 100644 --- a/clang/test/SemaCXX/unreachable-code.cpp +++ b/clang/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/clang/test/SemaCXX/warn-unreachable.cpp b/clang/test/SemaCXX/warn-unreachable.cpp index eab8d8e6..8acaf42 100644 --- a/clang/test/SemaCXX/warn-unreachable.cpp +++ b/clang/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/clang/test/SemaObjC/warn-unreachable.m b/clang/test/SemaObjC/warn-unreachable.m index 979b905..859bd00 100644 --- a/clang/test/SemaObjC/warn-unreachable.m +++ b/clang/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; + } +} + |