Fixed #3069 (False positive: Memory leak: data)
This commit is contained in:
parent
d098ed6031
commit
46b5d5bd00
102
lib/tokenize.cpp
102
lib/tokenize.cpp
|
@ -4755,6 +4755,9 @@ bool Tokenizer::simplifyTokenList()
|
||||||
modified |= simplifyCalculations();
|
modified |= simplifyCalculations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simplify redundant for
|
||||||
|
removeRedundantFor();
|
||||||
|
|
||||||
// Remove redundant parentheses in return..
|
// Remove redundant parentheses in return..
|
||||||
for (Token *tok = _tokens; tok; tok = tok->next())
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
{
|
{
|
||||||
|
@ -5004,6 +5007,105 @@ bool Tokenizer::removeReduntantConditions()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Tokenizer::removeRedundantFor()
|
||||||
|
{
|
||||||
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (Token::Match(tok, "[;{}] for ( %var% = %num% ; %var% < %num% ; ++| %var% ++| ) {"))
|
||||||
|
{
|
||||||
|
// Same variable name..
|
||||||
|
const std::string varname(tok->tokAt(3)->str());
|
||||||
|
const unsigned int varid(tok->tokAt(3)->varId());
|
||||||
|
if (varname != tok->tokAt(7)->str())
|
||||||
|
continue;
|
||||||
|
const Token *vartok = tok->tokAt(11);
|
||||||
|
if (vartok->str() == "++")
|
||||||
|
vartok = vartok->next();
|
||||||
|
if (varname != vartok->str())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check that the difference of the numeric values is 1
|
||||||
|
const MathLib::bigint num1(MathLib::toLongNumber(tok->strAt(5)));
|
||||||
|
const MathLib::bigint num2(MathLib::toLongNumber(tok->strAt(9)));
|
||||||
|
if (num1 + 1 != num2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// check how loop variable is used in loop..
|
||||||
|
bool read = false;
|
||||||
|
bool write = false;
|
||||||
|
unsigned int indentlevel = 0;
|
||||||
|
for (const Token *tok2 = tok->tokAt(2)->link(); tok2; tok2 = tok2->next())
|
||||||
|
{
|
||||||
|
if (tok2->str() == "{")
|
||||||
|
++indentlevel;
|
||||||
|
else if (tok2->str() == "}")
|
||||||
|
{
|
||||||
|
if (indentlevel <= 1)
|
||||||
|
break;
|
||||||
|
--indentlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok2->str() == varname)
|
||||||
|
{
|
||||||
|
if (tok2->previous()->isArithmeticalOp() &&
|
||||||
|
tok2->next() &&
|
||||||
|
(tok2->next()->isArithmeticalOp() || tok2->next()->str() == ";"))
|
||||||
|
{
|
||||||
|
read = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read = write = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simplify loop if loop variable isn't written
|
||||||
|
if (!write)
|
||||||
|
{
|
||||||
|
// remove "for ("
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
|
||||||
|
// If loop variable is read then keep assignment before
|
||||||
|
// loop body..
|
||||||
|
if (read)
|
||||||
|
{
|
||||||
|
// goto ";"
|
||||||
|
tok = tok->tokAt(4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove "x = 0 ;"
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove "x < 1 ; x ++ )"
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
tok->deleteNext();
|
||||||
|
|
||||||
|
// Add assignment after the loop body so the loop variable
|
||||||
|
// get the correct end value
|
||||||
|
Token *tok2 = tok->next()->link();
|
||||||
|
tok2->insertToken(";");
|
||||||
|
tok2->insertToken(MathLib::toString(num2));
|
||||||
|
tok2->insertToken("=");
|
||||||
|
tok2->insertToken(varname);
|
||||||
|
tok2->next()->varId(varid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Tokenizer::removeRedundantSemicolons()
|
void Tokenizer::removeRedundantSemicolons()
|
||||||
{
|
{
|
||||||
|
|
|
@ -359,6 +359,13 @@ public:
|
||||||
*/
|
*/
|
||||||
bool removeReduntantConditions();
|
bool removeReduntantConditions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove redundant for:
|
||||||
|
* "for (x=0;x<1;x++) { }" => "{ x = 1; }"
|
||||||
|
*/
|
||||||
|
void removeRedundantFor();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reduces "; ;" to ";", except in "( ; ; )"
|
* Reduces "; ;" to ";", except in "( ; ; )"
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -376,6 +376,11 @@ private:
|
||||||
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
|
TEST_CASE(simplifyVarDecl1); // ticket # 2682 segmentation fault
|
||||||
TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault
|
TEST_CASE(simplifyVarDecl2); // ticket # 2834 segmentation fault
|
||||||
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
|
TEST_CASE(return_strncat); // ticket # 2860 Returning value of strncat() reported as memory leak
|
||||||
|
|
||||||
|
// #3069 : for loop with 1 iteration
|
||||||
|
// for (x=0;x<1;x++) { .. }
|
||||||
|
// The for is redundant
|
||||||
|
TEST_CASE(removeRedundantFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[], bool simplify = true)
|
std::string tok(const char code[], bool simplify = true)
|
||||||
|
@ -7385,6 +7390,27 @@ private:
|
||||||
"return temp ; "
|
"return temp ; "
|
||||||
"}", tok(code, true));
|
"}", tok(code, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void removeRedundantFor() // ticket #3069
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char code[] = "void f() {"
|
||||||
|
" for(x=0;x<1;x++) {"
|
||||||
|
" y = 1;"
|
||||||
|
" }"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS("void f ( ) { { y = 1 ; } x = 1 ; }", tok(code, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "void f() {"
|
||||||
|
" for(x=0;x<1;x++) {"
|
||||||
|
" y = 1 + x;"
|
||||||
|
" }"
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS("void f ( ) { x = 0 ; { y = 1 + x ; } x = 1 ; }", tok(code, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyTokens)
|
REGISTER_TEST(TestSimplifyTokens)
|
||||||
|
|
Loading…
Reference in New Issue