Fix ticket #386 (False positive (memory leak) with comma)
http://apps.sourceforge.net/trac/cppcheck/ticket/386
This commit is contained in:
parent
d8f95f68c3
commit
092bd79ec4
|
@ -302,7 +302,7 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
||||||
if (str[0] == '%')
|
if (str[0] == '%')
|
||||||
{
|
{
|
||||||
// Any symbolname..
|
// Any symbolname..
|
||||||
if (strcmp(str, "%var%") == 0 || strcmp(str, "%type%") == 0)
|
if (strcmp(str, "%var%") == 0)
|
||||||
{
|
{
|
||||||
if (!tok->isName())
|
if (!tok->isName())
|
||||||
return false;
|
return false;
|
||||||
|
@ -310,6 +310,18 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
||||||
patternIdentified = true;
|
patternIdentified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type..
|
||||||
|
if (strcmp(str, "%type%") == 0)
|
||||||
|
{
|
||||||
|
if (!tok->isName())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tok->str() == "delete")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
patternIdentified = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Accept any token
|
// Accept any token
|
||||||
else if (strcmp(str, "%any%") == 0)
|
else if (strcmp(str, "%any%") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,6 +77,7 @@ public:
|
||||||
* Possible patterns
|
* Possible patterns
|
||||||
* "%any%" any token
|
* "%any%" any token
|
||||||
* "%var%" any token which is a name or type e.g. "hello" or "int"
|
* "%var%" any token which is a name or type e.g. "hello" or "int"
|
||||||
|
* "%type%" Anything that can be a variable type, e.g. "int", but not "delete".
|
||||||
* "%num%" Any numeric token, e.g. "23"
|
* "%num%" Any numeric token, e.g. "23"
|
||||||
* "%bool%" true or false
|
* "%bool%" true or false
|
||||||
* "%str%" Any token starting with "-character (C-string).
|
* "%str%" Any token starting with "-character (C-string).
|
||||||
|
@ -105,6 +106,7 @@ public:
|
||||||
bool isNumber() const;
|
bool isNumber() const;
|
||||||
bool isBoolean() const;
|
bool isBoolean() const;
|
||||||
bool isStandardType() const;
|
bool isStandardType() const;
|
||||||
|
|
||||||
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId = 0);
|
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1483,6 +1483,7 @@ void Tokenizer::simplifyTokenList()
|
||||||
modified |= simplifyQuestionMark();
|
modified |= simplifyQuestionMark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simplifyCommaNearKeyWords();
|
||||||
createLinks();
|
createLinks();
|
||||||
if (_settings._debug)
|
if (_settings._debug)
|
||||||
{
|
{
|
||||||
|
@ -2913,4 +2914,22 @@ void Tokenizer::syntaxError(const Token *tok, char c)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Tokenizer::simplifyCommaNearKeyWords()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() != ",")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We must not accept just any keyword, e.g. accepting int
|
||||||
|
// would cause function parameters to corrupt.
|
||||||
|
if (!Token::Match(tok->next(), "delete"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tok->str(";");
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -97,6 +97,8 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplify variable declarations
|
* Simplify variable declarations
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
*/
|
*/
|
||||||
bool simplifyVarDecl();
|
bool simplifyVarDecl();
|
||||||
|
|
||||||
|
@ -109,27 +111,43 @@ public:
|
||||||
/**
|
/**
|
||||||
* Simplify question mark - colon operator
|
* Simplify question mark - colon operator
|
||||||
* Example: 0 ? (2/0) : 0 => 0
|
* Example: 0 ? (2/0) : 0 => 0
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
*/
|
*/
|
||||||
bool simplifyQuestionMark();
|
bool simplifyQuestionMark();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simplify if-assignments..
|
* simplify if-assignments..
|
||||||
* Example: "if(a=b);" => "a=b;if(a);"
|
* Example: "if(a=b);" => "a=b;if(a);"
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
*/
|
*/
|
||||||
bool simplifyIfAssign();
|
bool simplifyIfAssign();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simplify if-not..
|
* simplify if-not..
|
||||||
* Example: "if(0==x);" => "if(!x);"
|
* Example: "if(0==x);" => "if(!x);"
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
*/
|
*/
|
||||||
bool simplifyIfNot();
|
bool simplifyIfNot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simplify the "not" keyword to "!"
|
* simplify the "not" keyword to "!"
|
||||||
* Example: "if (not p)" => "if (!p)"
|
* Example: "if (not p)" => "if (!p)"
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
*/
|
*/
|
||||||
bool simplifyNot();
|
bool simplifyNot();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplify comma near keywords into a semicolon
|
||||||
|
* Example: "delete a, delete b" => "delete a; delete b;"
|
||||||
|
* @return true if something is modified
|
||||||
|
* false if nothing is done.
|
||||||
|
*/
|
||||||
|
bool simplifyCommaNearKeyWords();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Add braces to an if-block
|
/** Add braces to an if-block
|
||||||
|
|
|
@ -105,6 +105,7 @@ private:
|
||||||
|
|
||||||
// Simplify "not" to "!" (#345)
|
// Simplify "not" to "!" (#345)
|
||||||
TEST_CASE(not1);
|
TEST_CASE(not1);
|
||||||
|
TEST_CASE(comma_keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[])
|
std::string tok(const char code[])
|
||||||
|
@ -932,6 +933,15 @@ private:
|
||||||
ASSERT_EQUALS("void foo ( not i )", simplifyNot("void foo ( not i )"));
|
ASSERT_EQUALS("void foo ( not i )", simplifyNot("void foo ( not i )"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void comma_keyword()
|
||||||
|
{
|
||||||
|
const char code[] = "void foo()\n"
|
||||||
|
"{\n"
|
||||||
|
" char *a, *b;\n"
|
||||||
|
" delete a, delete b;\n"
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(" void foo ( ) { char * a ; char * b ; delete a ; delete b ; }", sizeof_(code));
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue