Fix ticket #386 (False positive (memory leak) with comma)

http://apps.sourceforge.net/trac/cppcheck/ticket/386
This commit is contained in:
Reijo Tomperi 2009-06-11 00:12:26 +03:00
parent d8f95f68c3
commit 092bd79ec4
5 changed files with 62 additions and 1 deletions

View File

@ -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)
{ {

View File

@ -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);
/** /**

View File

@ -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;
}

View File

@ -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

View File

@ -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));
}
}; };