Fixed #1574 (chain assignments could be simplified)

http://sourceforge.net/apps/trac/cppcheck/ticket/1574
This commit is contained in:
Slava Semushin 2010-05-01 15:26:15 +07:00
parent 080374dc04
commit f50d182750
3 changed files with 87 additions and 1 deletions

View File

@ -1400,6 +1400,8 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
// Split up variable declarations. // Split up variable declarations.
simplifyVarDecl(); simplifyVarDecl();
simplifyVariableMultipleAssign();
// Change initialisation of variable to assignment // Change initialisation of variable to assignment
simplifyInitVar(); simplifyInitVar();
@ -4645,6 +4647,43 @@ void Tokenizer::simplifyIfAssign()
} }
void Tokenizer::simplifyVariableMultipleAssign()
{
for (Token *tok = _tokens; tok; tok = tok->next())
{
if (Token::Match(tok, "%var% = %var% = %num% ;") ||
Token::Match(tok, "%var% = %var% = %var% ;"))
{
// skip intermediate assignments
Token *tok2 = tok->previous();
while (tok2 &&
tok2->str() == "=" &&
Token::Match(tok2->previous(), "%var%"))
{
tok2 = tok2->tokAt(-2);
}
if (tok2->str() != ";")
{
continue;
}
Token *stopAt = tok->tokAt(2);
const Token *valueTok = tok->tokAt(4);
const std::string value(valueTok->str());
tok2 = tok2->next();
while (tok2 != stopAt)
{
tok2->next()->insertToken(";");
tok2->next()->insertToken(value);
tok2 = tok2->tokAt(4);
}
}
}
}
void Tokenizer::simplifyIfNot() void Tokenizer::simplifyIfNot()
{ {

View File

@ -187,6 +187,12 @@ public:
*/ */
void simplifyIfAssign(); void simplifyIfAssign();
/**
* Simplify multiple assignmetns.
* Example: "a = b = c = 0;" => "a = 0; b = 0; c = 0;"
*/
void simplifyVariableMultipleAssign();
/** /**
* simplify if-not * simplify if-not
* Example: "if(0==x);" => "if(!x);" * Example: "if(0==x);" => "if(!x);"

View File

@ -74,6 +74,7 @@ private:
TEST_CASE(localvar9); // ticket #1605 TEST_CASE(localvar9); // ticket #1605
TEST_CASE(localvar10); TEST_CASE(localvar10);
TEST_CASE(localvar11); TEST_CASE(localvar11);
TEST_CASE(localvar12);
TEST_CASE(localvaralias1); TEST_CASE(localvaralias1);
TEST_CASE(localvaralias2); // ticket #1637 TEST_CASE(localvaralias2); // ticket #1637
TEST_CASE(localvarasm); TEST_CASE(localvarasm);
@ -892,7 +893,11 @@ private:
" int a, b, c;\n" " int a, b, c;\n"
" a = b = c = 0;\n" " a = b = c = 0;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n", errout.str()); ASSERT_EQUALS(
"[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'c' is assigned a value that is never used\n",
errout.str());
functionVariableUsage("int * foo()\n" functionVariableUsage("int * foo()\n"
"{\n" "{\n"
@ -998,6 +1003,42 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void localvar12()
{
// ticket #1574
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c, d, e, f;\n"
" a = b = c = d = e = f = 0;\n"
"\n"
"}\n");
ASSERT_EQUALS(
"[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'c' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'd' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'e' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'f' is assigned a value that is never used\n",
errout.str());
functionVariableUsage("void foo()\n"
"{\n"
" int a, b, c = 0;\n"
" a = b = c;\n"
"\n"
"}\n");
ASSERT_EQUALS(
"[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n",
errout.str());
TODO_ASSERT_EQUALS(
"[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'b' is assigned a value that is never used\n"
"[test.cpp:3]: (style) Variable 'c' is assigned a value that is never used\n",
errout.str());
}
void localvaralias1() void localvaralias1()
{ {
functionVariableUsage("void foo()\n" functionVariableUsage("void foo()\n"