Fixed #2147 (uninitialized variable: false negative for 'x += y;')
This commit is contained in:
parent
8d96697623
commit
23d3fd3a5a
|
@ -1032,7 +1032,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
|||
}
|
||||
|
||||
if (Token::Match(tok->previous(), "[;{})=] %var%") ||
|
||||
Token::Match(tok->previous(), "|= %var%"))
|
||||
Token::Match(tok->previous(), "| %var%"))
|
||||
{
|
||||
AllocType dealloc = getDeallocationType(tok, varid);
|
||||
|
||||
|
|
|
@ -1840,11 +1840,16 @@ bool Tokenizer::tokenize(std::istream &code,
|
|||
{
|
||||
tok->str(tok->str() + c2);
|
||||
tok->deleteNext();
|
||||
if (c1 == '<' && tok->next()->str() == "=")
|
||||
{
|
||||
tok->str("<<=");
|
||||
tok->deleteNext();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// combine +-*/ and =
|
||||
else if (c2 == '=' && (strchr("+-*/&|=!<>", c1)))
|
||||
else if (c2 == '=' && (strchr("+-*/%&|^=!<>", c1)))
|
||||
{
|
||||
tok->str(tok->str() + c2);
|
||||
tok->deleteNext();
|
||||
|
@ -1860,6 +1865,12 @@ bool Tokenizer::tokenize(std::istream &code,
|
|||
}
|
||||
}
|
||||
|
||||
else if (tok->str() == ">>" && tok->next()->str() == "=")
|
||||
{
|
||||
tok->str(">>=");
|
||||
tok->deleteNext();
|
||||
}
|
||||
|
||||
else if ((c1 == 'p' || c1 == '_') && tok->next()->str() == ":")
|
||||
{
|
||||
if (tok->str() == "private" || tok->str() == "protected" || tok->str() == "public" || tok->str() == "__published")
|
||||
|
@ -1871,6 +1882,9 @@ bool Tokenizer::tokenize(std::istream &code,
|
|||
}
|
||||
}
|
||||
|
||||
// ";a+=b;" => ";a=a+b;"
|
||||
simplifyCompoundAssignment();
|
||||
|
||||
// check for more complicated syntax errors when using templates..
|
||||
if (!preprocessorCondition)
|
||||
{
|
||||
|
@ -4349,6 +4363,31 @@ void Tokenizer::simplifyDoWhileAddBraces()
|
|||
}
|
||||
}
|
||||
|
||||
void Tokenizer::simplifyCompoundAssignment()
|
||||
{
|
||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||
{
|
||||
if (Token::Match(tok, "; %var%"))
|
||||
{
|
||||
const Token *vartok = tok->next();
|
||||
const std::string str = tok->strAt(2);
|
||||
std::string op;
|
||||
if (str.size() == 2 && str[1] == '=' && str.find_first_of("+-*/%&|^")==0)
|
||||
op = str.substr(0, 1);
|
||||
else if (str=="<<=" || str==">>=")
|
||||
op = str.substr(0, 2);
|
||||
else
|
||||
continue;
|
||||
|
||||
tok = tok->tokAt(2);
|
||||
tok->str("=");
|
||||
tok->insertToken(op);
|
||||
tok->insertToken(vartok->str());
|
||||
tok->next()->varId(vartok->varId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::simplifyConditionOperator()
|
||||
{
|
||||
int parlevel = 0;
|
||||
|
|
|
@ -193,6 +193,12 @@ public:
|
|||
*/
|
||||
bool simplifyQuestionMark();
|
||||
|
||||
/**
|
||||
* Simplify compound assignments
|
||||
* Example: ";a+=b;" => ";a=a+b;"
|
||||
*/
|
||||
void simplifyCompoundAssignment();
|
||||
|
||||
/**
|
||||
* simplify if-assignments
|
||||
* Example: "if(a=b);" => "a=b;if(a);"
|
||||
|
|
|
@ -267,6 +267,9 @@ private:
|
|||
// foo(p = new char[10]); => p = new char[10]; foo(p);
|
||||
TEST_CASE(simplifyAssignmentInFunctionCall);
|
||||
|
||||
// "x += .." => "x = x + .."
|
||||
TEST_CASE(simplifyCompoundAssignment);
|
||||
|
||||
// Tokenize C#
|
||||
TEST_CASE(cs);
|
||||
|
||||
|
@ -4583,6 +4586,20 @@ private:
|
|||
ASSERT_EQUALS("if ( a != b )", tokenizeAndStringify("if (a not_eq b)"));
|
||||
}
|
||||
|
||||
void simplifyCompoundAssignment()
|
||||
{
|
||||
ASSERT_EQUALS("; x = x + y ;", tokenizeAndStringify("; x += y;"));
|
||||
ASSERT_EQUALS("; x = x - y ;", tokenizeAndStringify("; x -= y;"));
|
||||
ASSERT_EQUALS("; x = x * y ;", tokenizeAndStringify("; x *= y;"));
|
||||
ASSERT_EQUALS("; x = x / y ;", tokenizeAndStringify("; x /= y;"));
|
||||
ASSERT_EQUALS("; x = x % y ;", tokenizeAndStringify("; x %= y;"));
|
||||
ASSERT_EQUALS("; x = x & y ;", tokenizeAndStringify("; x &= y;"));
|
||||
ASSERT_EQUALS("; x = x | y ;", tokenizeAndStringify("; x |= y;"));
|
||||
ASSERT_EQUALS("; x = x ^ y ;", tokenizeAndStringify("; x ^= y;"));
|
||||
ASSERT_EQUALS("; x = x << y ;", tokenizeAndStringify("; x <<= y;"));
|
||||
ASSERT_EQUALS("; x = x >> y ;", tokenizeAndStringify("; x >>= y;"));
|
||||
}
|
||||
|
||||
void simplifyAssignmentInFunctionCall()
|
||||
{
|
||||
ASSERT_EQUALS("; x = g ( ) ; f ( x ) ;", tokenizeAndStringify(";f(x=g());"));
|
||||
|
|
|
@ -2281,7 +2281,8 @@ private:
|
|||
" int b = 2;\n"
|
||||
" a |= b;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' 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", errout.str());
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void localvarFor()
|
||||
|
|
Loading…
Reference in New Issue