diff --git a/lib/checkother.cpp b/lib/checkother.cpp index a9f6dcd91..048d94b44 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -476,7 +476,7 @@ struct CheckOther::ScopeResult CheckOther::checkRedundantAssignmentRecursive(con } if (Token::simpleMatch(tok, "break ;")) { - return ScopeResult(ScopeResult::BREAK); + return ScopeResult(ScopeResult::BREAK, tok); } if (Token::Match(tok, "continue|return|throw|goto")) { @@ -609,7 +609,26 @@ void CheckOther::checkRedundantAssignment() start = tok->next(); else start = tok->findExpressionStartEndTokens().second->next(); - const ScopeResult &nextAssign = checkRedundantAssignmentRecursive(tok, start, scope->bodyEnd); + + // Get next assignment.. + ScopeResult nextAssign(ScopeResult::NONE); + while (true) { + nextAssign = checkRedundantAssignmentRecursive(tok, start, scope->bodyEnd); + + // Break => continue checking in outer scope + if (nextAssign.type == ScopeResult::BREAK) { + const Scope *s = nextAssign.token->scope(); + while (s->type == Scope::eIf) + s = s->nestedIn; + if (s->type == Scope::eSwitch) { + start = s->bodyEnd->next(); + continue; + } + } + + break; + } + if (nextAssign.type != ScopeResult::WRITE || !nextAssign.token) continue; diff --git a/test/testother.cpp b/test/testother.cpp index d4d385503..f6dfcb898 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -164,6 +164,7 @@ private: TEST_CASE(redundantVarAssignment_stackoverflow); TEST_CASE(redundantVarAssignment_lambda); TEST_CASE(redundantVarAssignment_for); + TEST_CASE(redundantVarAssignment_after_switch); TEST_CASE(redundantMemWrite); TEST_CASE(varFuncNullUB); @@ -6070,6 +6071,19 @@ private: ASSERT_EQUALS("", errout.str()); } + void redundantVarAssignment_after_switch() { + check("void f(int x) {\n" // #7907 + " int ret;\n" + " switch (x) {\n" + " case 123:\n" + " ret = 1;\n" // redundant assignment + " break;\n" + " }\n" + " ret = 3;\n" + "}"); + ASSERT_EQUALS("[test.cpp:5] -> [test.cpp:8]: (style) Variable 'ret' is reassigned a value before the old one has been used.\n", errout.str()); + } + void redundantMemWrite() { return; // FIXME: temporary hack