Fixed #7907 (FN: redundant assignment inside switchcase, overwritten by assignment outside of switch)

This commit is contained in:
Daniel Marjamäki 2018-12-02 14:04:59 +01:00
parent 88785dda02
commit ba564076db
2 changed files with 35 additions and 2 deletions

View File

@ -476,7 +476,7 @@ struct CheckOther::ScopeResult CheckOther::checkRedundantAssignmentRecursive(con
} }
if (Token::simpleMatch(tok, "break ;")) { if (Token::simpleMatch(tok, "break ;")) {
return ScopeResult(ScopeResult::BREAK); return ScopeResult(ScopeResult::BREAK, tok);
} }
if (Token::Match(tok, "continue|return|throw|goto")) { if (Token::Match(tok, "continue|return|throw|goto")) {
@ -609,7 +609,26 @@ void CheckOther::checkRedundantAssignment()
start = tok->next(); start = tok->next();
else else
start = tok->findExpressionStartEndTokens().second->next(); 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) if (nextAssign.type != ScopeResult::WRITE || !nextAssign.token)
continue; continue;

View File

@ -164,6 +164,7 @@ private:
TEST_CASE(redundantVarAssignment_stackoverflow); TEST_CASE(redundantVarAssignment_stackoverflow);
TEST_CASE(redundantVarAssignment_lambda); TEST_CASE(redundantVarAssignment_lambda);
TEST_CASE(redundantVarAssignment_for); TEST_CASE(redundantVarAssignment_for);
TEST_CASE(redundantVarAssignment_after_switch);
TEST_CASE(redundantMemWrite); TEST_CASE(redundantMemWrite);
TEST_CASE(varFuncNullUB); TEST_CASE(varFuncNullUB);
@ -6070,6 +6071,19 @@ private:
ASSERT_EQUALS("", errout.str()); 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() { void redundantMemWrite() {
return; // FIXME: temporary hack return; // FIXME: temporary hack