Fixed #7907 (FN: redundant assignment inside switchcase, overwritten by assignment outside of switch)
This commit is contained in:
parent
88785dda02
commit
ba564076db
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue