diff --git a/lib/checkother.cpp b/lib/checkother.cpp index cce598aaf7c..6bf10846de5 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -762,6 +762,18 @@ void CheckOther::suspiciousCaseInSwitchError(const Token* tok, const std::string "Using an operator like '" + operatorString + "' in a case label is suspicious. Did you intend to use a bitwise operator, multiple case labels or if/else instead?", CWE398, Certainty::inconclusive); } +static bool isLastStmtContinue(const Token* secondBreak, const Token* tok) +{ + if (tok->str() != "continue") + return false; + while (Token::simpleMatch(secondBreak, "}")) { + if (secondBreak->scope() && secondBreak->scope()->isLoopScope()) + return true; + secondBreak = secondBreak->next(); + } + return false; +} + //--------------------------------------------------------------------------- // Find consecutive return, break, continue, goto or throw statements. e.g.: // break; break; @@ -863,7 +875,7 @@ void CheckOther::checkUnreachableCode() if (!labelInFollowingLoop && !silencedCompilerWarningOnly) unreachableCodeError(secondBreak, tok, inconclusive); tok = Token::findmatch(secondBreak, "[}:]"); - } else if (secondBreak->scope() && secondBreak->scope()->isLoopScope() && secondBreak->str() == "}" && tok->str() == "continue") { + } else if (isLastStmtContinue(secondBreak, tok)) { redundantContinueError(tok); tok = secondBreak; } else diff --git a/test/testother.cpp b/test/testother.cpp index b7031723301..38998423876 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -5322,6 +5322,15 @@ class TestOther : public TestFixture { " } while (i < 10);\n" "}\n"); ASSERT_EQUALS("[test.cpp:5]: (style) 'continue' is redundant since it is the last statement in a loop.\n", errout_str()); + + check("void f(bool b, const std::list& l) {\n" // #12527 + " for (int i : l) {\n" + " (void)i;\n" + " if (b)\n" + " continue;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5]: (style) 'continue' is redundant since it is the last statement in a loop.\n", errout_str()); }