Unused value: Fixed false negatives for loops
This commit is contained in:
parent
3262a3bebe
commit
3af0d73f82
|
@ -1065,11 +1065,6 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
|
||||||
return Result(Result::Type::BAILOUT);
|
return Result(Result::Type::BAILOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->str() == "}" && (tok->scope()->type == Scope::eFor || tok->scope()->type == Scope::eWhile)) {
|
|
||||||
// TODO: handle loops better
|
|
||||||
return Result(Result::Type::BAILOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "break ;")) {
|
if (Token::simpleMatch(tok, "break ;")) {
|
||||||
return Result(Result::Type::BREAK, tok);
|
return Result(Result::Type::BREAK, tok);
|
||||||
}
|
}
|
||||||
|
@ -1097,17 +1092,19 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
|
||||||
|
|
||||||
if (tok->str() == "}") {
|
if (tok->str() == "}") {
|
||||||
Scope::ScopeType scopeType = tok->scope()->type;
|
Scope::ScopeType scopeType = tok->scope()->type;
|
||||||
if (scopeType == Scope::eWhile || scopeType == Scope::eFor || scopeType == Scope::eDo)
|
if (scopeType == Scope::eWhile || scopeType == Scope::eFor || scopeType == Scope::eDo) {
|
||||||
// TODO handle loops better
|
// TODO: check condition
|
||||||
return Result(Result::Type::BAILOUT);
|
const struct FwdAnalysis::Result &result = checkRecursive(expr, tok->link(), tok, exprVarIds, local);
|
||||||
|
if (result.type == Result::Type::BAILOUT || result.type == Result::Type::READ)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "else {"))
|
if (Token::simpleMatch(tok, "else {"))
|
||||||
tok = tok->linkAt(1);
|
tok = tok->linkAt(1);
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "asm (")) {
|
if (Token::simpleMatch(tok, "asm ("))
|
||||||
return Result(Result::Type::BAILOUT);
|
return Result(Result::Type::BAILOUT);
|
||||||
}
|
|
||||||
|
|
||||||
if (!local && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
if (!local && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) {
|
||||||
// TODO: this is a quick bailout
|
// TODO: this is a quick bailout
|
||||||
|
@ -1255,7 +1252,7 @@ FwdAnalysis::Result FwdAnalysis::check(const Token *expr, const Token *startToke
|
||||||
const Scope *s = result.token->scope();
|
const Scope *s = result.token->scope();
|
||||||
while (s->type == Scope::eIf)
|
while (s->type == Scope::eIf)
|
||||||
s = s->nestedIn;
|
s = s->nestedIn;
|
||||||
if (s->type != Scope::eSwitch)
|
if (s->type != Scope::eSwitch && s->type != Scope::eWhile && s->type != Scope::eFor)
|
||||||
break;
|
break;
|
||||||
result = checkRecursive(expr, s->bodyEnd->next(), endToken, exprVarIds, local);
|
result = checkRecursive(expr, s->bodyEnd->next(), endToken, exprVarIds, local);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,7 @@ private:
|
||||||
TEST_CASE(localvar52);
|
TEST_CASE(localvar52);
|
||||||
TEST_CASE(localvar53); // continue
|
TEST_CASE(localvar53); // continue
|
||||||
TEST_CASE(localvar54); // ast, {}
|
TEST_CASE(localvar54); // ast, {}
|
||||||
|
TEST_CASE(localvarloops); // loops
|
||||||
TEST_CASE(localvaralias1);
|
TEST_CASE(localvaralias1);
|
||||||
TEST_CASE(localvaralias2); // ticket #1637
|
TEST_CASE(localvaralias2); // ticket #1637
|
||||||
TEST_CASE(localvaralias3); // ticket #1639
|
TEST_CASE(localvaralias3); // ticket #1639
|
||||||
|
@ -746,7 +747,9 @@ private:
|
||||||
" d = code;\n"
|
" d = code;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used.\n"
|
||||||
|
"[test.cpp:7]: (style) Variable 'd' is assigned a value that is never used.\n",
|
||||||
|
errout.str());
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2119,6 +2122,39 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void localvarloops() {
|
||||||
|
// loops
|
||||||
|
functionVariableUsage("void fun() {\n"
|
||||||
|
" int x;\n"
|
||||||
|
" while (c) { x=10; }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage("void fun() {\n"
|
||||||
|
" int x = 1;\n"
|
||||||
|
" while (c) {\n"
|
||||||
|
" dostuff(x);\n"
|
||||||
|
" if (y) { x=10; break; }\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage("void fun() {\n"
|
||||||
|
" int x = 0;\n"
|
||||||
|
" while (c) {\n"
|
||||||
|
" dostuff(x);\n"
|
||||||
|
" x = 10;\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
functionVariableUsage("void fun() {\n"
|
||||||
|
" int x = 0;\n"
|
||||||
|
" while (x < 10) { x = x + 1; }\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void localvaralias1() {
|
void localvaralias1() {
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue