Refactorizations:
- Replaced some indendation counters by Token::link() or usage of symbolDatabase - Use Token::nextArgument() to jump to target parameter
This commit is contained in:
parent
6d9b4a8032
commit
710fefeef0
|
@ -495,61 +495,53 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok,
|
||||||
const char *CheckMemoryLeak::functionArgAlloc(const Token *tok, unsigned int targetpar, AllocType &allocType) const
|
const char *CheckMemoryLeak::functionArgAlloc(const Token *tok, unsigned int targetpar, AllocType &allocType) const
|
||||||
{
|
{
|
||||||
// Find the varid of targetpar, then locate the start of the function..
|
// Find the varid of targetpar, then locate the start of the function..
|
||||||
unsigned int parlevel = 0;
|
|
||||||
unsigned int par = 0;
|
|
||||||
unsigned int varid = 0;
|
unsigned int varid = 0;
|
||||||
|
|
||||||
allocType = No;
|
allocType = No;
|
||||||
|
|
||||||
while (tok) {
|
// Locate start of arguments
|
||||||
if (tok->str() == "{" || tok->str() == "}")
|
tok = Token::findsimplematch(tok, "(");
|
||||||
|
if (!tok)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (tok->str() == "(") {
|
// Is this the start of a function?
|
||||||
if (parlevel != 0)
|
const Token* const fstart = tok->link();
|
||||||
|
if (!Token::Match(fstart, ") const| {"))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
// Locate targetpar
|
||||||
|
tok = tok->next();
|
||||||
|
for (unsigned int par = 1; par < targetpar; par++) {
|
||||||
|
tok = tok->nextArgument();
|
||||||
|
if (tok == 0)
|
||||||
return "";
|
return "";
|
||||||
++parlevel;
|
|
||||||
++par;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (tok->str() == ")") {
|
while (tok) {
|
||||||
if (parlevel != 1)
|
if (tok->str() == "(")
|
||||||
return "";
|
tok = tok->link();
|
||||||
|
else if (tok->str() == ",")
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (Token::Match(tok, "%type% * * %var%")) {
|
||||||
|
varid = tok->tokAt(3)->varId();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (parlevel == 1 && tok->str() == ",") {
|
|
||||||
++par;
|
|
||||||
}
|
|
||||||
|
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
|
||||||
if (parlevel == 1 && par == targetpar && Token::Match(tok, "%type% * * %var%")) {
|
|
||||||
varid = tok->tokAt(3)->varId();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varid == 0)
|
if (varid == 0)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// Is this the start of a function?
|
// continue in function body
|
||||||
if (!Token::Match(tok, ") const| {"))
|
tok = fstart;
|
||||||
return "";
|
|
||||||
|
|
||||||
while (tok->str() != "{")
|
while (tok->str() != "{")
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
|
||||||
// Check if pointer is allocated.
|
// Check if pointer is allocated.
|
||||||
unsigned int indentlevel = 0;
|
|
||||||
int realloc = 0;
|
int realloc = 0;
|
||||||
while (NULL != (tok = tok->next())) {
|
for (const Token* const end = tok->link(); tok && tok != end; tok = tok->next()) {
|
||||||
if (tok->str() == "{")
|
if (tok->varId() == varid) {
|
||||||
++indentlevel;
|
|
||||||
else if (tok->str() == "}") {
|
|
||||||
if (indentlevel <= 1)
|
|
||||||
break;
|
|
||||||
--indentlevel;
|
|
||||||
} else if (tok->varId() == varid) {
|
|
||||||
if (Token::Match(tok->tokAt(-3), "free ( * %varid% )", varid)) {
|
if (Token::Match(tok->tokAt(-3), "free ( * %varid% )", varid)) {
|
||||||
realloc = 1;
|
realloc = 1;
|
||||||
allocType = No;
|
allocType = No;
|
||||||
|
@ -598,27 +590,21 @@ void CheckMemoryLeakInFunction::parse_noreturn()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// parse this function to check if it contains an "exit" call..
|
// parse this function to check if it contains an "exit" call..
|
||||||
unsigned int indentlevel = 1;
|
bool isNoreturn = false;
|
||||||
for (const Token *tok2 = scope->classStart->next(); tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = scope->classStart->next(); tok2 != scope->classEnd; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "{")
|
|
||||||
++indentlevel;
|
|
||||||
else if (tok2->str() == "}") {
|
|
||||||
--indentlevel;
|
|
||||||
if (indentlevel == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (Token::Match(tok2->previous(), "[;{}] exit (")) {
|
if (Token::Match(tok2->previous(), "[;{}] exit (")) {
|
||||||
noreturn.insert(scope->className);
|
isNoreturn = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is not a noreturn function
|
// This function is not a noreturn function
|
||||||
if (indentlevel == 0) {
|
if (isNoreturn)
|
||||||
|
noreturn.insert(scope->className);
|
||||||
|
else
|
||||||
notnoreturn.insert(scope->className);
|
notnoreturn.insert(scope->className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CheckMemoryLeakInFunction::notvar(const Token *tok, unsigned int varid, bool endpar) const
|
bool CheckMemoryLeakInFunction::notvar(const Token *tok, unsigned int varid, bool endpar) const
|
||||||
|
@ -1173,10 +1159,12 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
|
|
||||||
// Loops..
|
// Loops..
|
||||||
else if ((tok->str() == "for") || (tok->str() == "while")) {
|
else if ((tok->str() == "for") || (tok->str() == "while")) {
|
||||||
|
const Token* const end = tok->linkAt(1);
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "while ( true )") ||
|
if (Token::simpleMatch(tok, "while ( true )") ||
|
||||||
Token::simpleMatch(tok, "for ( ; ; )")) {
|
Token::simpleMatch(tok, "for ( ; ; )")) {
|
||||||
addtoken(&rettail, tok, "while1");
|
addtoken(&rettail, tok, "while1");
|
||||||
tok = tok->next()->link();
|
tok = end;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1189,39 +1177,30 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
if (Token::Match(tok, "while ( 0 <= %varid% )", varid) ||
|
if (Token::Match(tok, "while ( 0 <= %varid% )", varid) ||
|
||||||
Token::Match(tok, "while ( %varid% != -1 )", varid)) {
|
Token::Match(tok, "while ( %varid% != -1 )", varid)) {
|
||||||
addtoken(&rettail, tok, "while(var)");
|
addtoken(&rettail, tok, "while(var)");
|
||||||
tok = tok->next()->link();
|
tok = end;
|
||||||
continue;
|
continue;
|
||||||
} else if (Token::Match(tok, "while ( %varid% == -1 )", varid) ||
|
} else if (Token::Match(tok, "while ( %varid% == -1 )", varid) ||
|
||||||
Token::Match(tok, "while ( %varid% < 0 )", varid)) {
|
Token::Match(tok, "while ( %varid% < 0 )", varid)) {
|
||||||
addtoken(&rettail, tok, "while(!var)");
|
addtoken(&rettail, tok, "while(!var)");
|
||||||
tok = tok->next()->link();
|
tok = end;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (varid && Token::Match(tok, "while ( %varid% )", varid)) {
|
else if (varid && Token::Match(tok, "while ( %varid% )", varid)) {
|
||||||
addtoken(&rettail, tok, "while(var)");
|
addtoken(&rettail, tok, "while(var)");
|
||||||
tok = tok->next()->link();
|
tok = end;
|
||||||
continue;
|
continue;
|
||||||
} else if (varid && Token::simpleMatch(tok, "while (") && notvar(tok->tokAt(2), varid, true)) {
|
} else if (varid && Token::simpleMatch(tok, "while (") && notvar(tok->tokAt(2), varid, true)) {
|
||||||
addtoken(&rettail, tok, "while(!var)");
|
addtoken(&rettail, tok, "while(!var)");
|
||||||
tok = tok->next()->link();
|
tok = end;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
addtoken(&rettail, tok, "loop");
|
addtoken(&rettail, tok, "loop");
|
||||||
|
|
||||||
if (varid > 0) {
|
if (varid > 0) {
|
||||||
unsigned int parlevel2 = 0;
|
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
|
|
||||||
if (tok2->str() == "(")
|
|
||||||
++parlevel2;
|
|
||||||
else if (tok2->str() == ")") {
|
|
||||||
if (parlevel2 > 0)
|
|
||||||
--parlevel2;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (notvar(tok2, varid)) {
|
if (notvar(tok2, varid)) {
|
||||||
addtoken(&rettail, tok2, "!var");
|
addtoken(&rettail, tok2, "!var");
|
||||||
break;
|
break;
|
||||||
|
@ -1259,9 +1238,7 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
|
|
||||||
// Returning a auto_ptr of this allocated variable..
|
// Returning a auto_ptr of this allocated variable..
|
||||||
if (Token::simpleMatch(tok->next(), "std :: auto_ptr <")) {
|
if (Token::simpleMatch(tok->next(), "std :: auto_ptr <")) {
|
||||||
const Token *tok2 = tok->tokAt(5);
|
const Token *tok2 = tok->linkAt(4);
|
||||||
while (tok2 && tok2->str() != ">")
|
|
||||||
tok2 = tok2->next();
|
|
||||||
if (Token::Match(tok2, "> ( %varid% )", varid)) {
|
if (Token::Match(tok2, "> ( %varid% )", varid)) {
|
||||||
addtoken(&rettail, tok, "use");
|
addtoken(&rettail, tok, "use");
|
||||||
tok = tok2->tokAt(3);
|
tok = tok2->tokAt(3);
|
||||||
|
@ -1313,16 +1290,10 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
// Assignment..
|
// Assignment..
|
||||||
if (varid) {
|
if (varid) {
|
||||||
if (Token::simpleMatch(tok, "= {")) {
|
if (Token::simpleMatch(tok, "= {")) {
|
||||||
unsigned int indentlevel2 = 0;
|
const Token* const end2 = tok->linkAt(1);
|
||||||
bool use = false;
|
bool use = false;
|
||||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok; tok2 != end2; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "{")
|
if (tok2->varId() == varid) {
|
||||||
++indentlevel2;
|
|
||||||
else if (tok2->str() == "}") {
|
|
||||||
if (indentlevel2 <= 1)
|
|
||||||
break;
|
|
||||||
--indentlevel2;
|
|
||||||
} else if (tok2->varId() == varid) {
|
|
||||||
use = true;
|
use = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1377,15 +1348,8 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list<const Toke
|
||||||
addtoken(&rettail, tok, "exit");
|
addtoken(&rettail, tok, "exit");
|
||||||
|
|
||||||
else if (!test_white_list(tok->str())) {
|
else if (!test_white_list(tok->str())) {
|
||||||
int innerParlevel = 1;
|
const Token* const end2 = tok->linkAt(1);
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "(")
|
|
||||||
++innerParlevel;
|
|
||||||
else if (tok2->str() == ")") {
|
|
||||||
--innerParlevel;
|
|
||||||
if (innerParlevel <= 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (tok2->varId() == varid) {
|
if (tok2->varId() == varid) {
|
||||||
addtoken(&rettail, tok, "::use");
|
addtoken(&rettail, tok, "::use");
|
||||||
break;
|
break;
|
||||||
|
@ -2787,17 +2751,8 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Token * const vartok
|
||||||
|
|
||||||
// Check if the struct is used..
|
// Check if the struct is used..
|
||||||
bool deallocated = false;
|
bool deallocated = false;
|
||||||
unsigned int parlevel = 0;
|
const Token* const end4 = tok3->linkAt(1);
|
||||||
for (const Token *tok4 = tok3; tok4; tok4 = tok4->next()) {
|
for (const Token *tok4 = tok3; tok4 != end4; tok4 = tok4->next()) {
|
||||||
if (tok4->str() == "(")
|
|
||||||
++parlevel;
|
|
||||||
|
|
||||||
else if (tok4->str() == ")") {
|
|
||||||
if (parlevel <= 1)
|
|
||||||
break;
|
|
||||||
--parlevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::Match(tok4, "[(,] &| %varid% [,)]", structid)) {
|
if (Token::Match(tok4, "[(,] &| %varid% [,)]", structid)) {
|
||||||
/** @todo check if the function deallocates the memory */
|
/** @todo check if the function deallocates the memory */
|
||||||
deallocated = true;
|
deallocated = true;
|
||||||
|
|
|
@ -307,8 +307,7 @@ public:
|
||||||
const Token *tok = it;
|
const Token *tok = it;
|
||||||
|
|
||||||
// Search for the start of the loop body..
|
// Search for the start of the loop body..
|
||||||
int indentlevel = 1;
|
while (0 != (tok = tok->next())) {
|
||||||
while (indentlevel > 0 && 0 != (tok = tok->next())) {
|
|
||||||
if (tok->str() == "(")
|
if (tok->str() == "(")
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
else if (tok->str() == ")")
|
else if (tok->str() == ")")
|
||||||
|
|
|
@ -735,18 +735,9 @@ private:
|
||||||
if (Token::Match(&tok, "( * %var% ) (") ||
|
if (Token::Match(&tok, "( * %var% ) (") ||
|
||||||
(Token::Match(&tok, "( *| %var% .|::") && Token::Match(tok.link()->tokAt(-2), ".|:: %var% ) ("))) {
|
(Token::Match(&tok, "( *| %var% .|::") && Token::Match(tok.link()->tokAt(-2), ".|:: %var% ) ("))) {
|
||||||
// is the variable passed as a parameter to some function?
|
// is the variable passed as a parameter to some function?
|
||||||
unsigned int parlevel = 0;
|
const Token *tok2 = tok.link()->next();
|
||||||
for (const Token *tok2 = tok.link()->next(); tok2; tok2 = tok2->next()) {
|
for (const Token* const end = tok2->link(); tok2 != end; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "(")
|
if (tok2->varId()) {
|
||||||
++parlevel;
|
|
||||||
|
|
||||||
else if (tok2->str() == ")") {
|
|
||||||
if (parlevel <= 1)
|
|
||||||
break;
|
|
||||||
--parlevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (tok2->varId()) {
|
|
||||||
// it is possible that the variable is initialized here
|
// it is possible that the variable is initialized here
|
||||||
ExecutionPath::bailOutVar(checks, tok2->varId());
|
ExecutionPath::bailOutVar(checks, tok2->varId());
|
||||||
}
|
}
|
||||||
|
@ -905,15 +896,9 @@ private:
|
||||||
return;
|
return;
|
||||||
if (Token::simpleMatch(tok, "if (")) {
|
if (Token::simpleMatch(tok, "if (")) {
|
||||||
// bail out all variables that are used in the condition
|
// bail out all variables that are used in the condition
|
||||||
unsigned int parlevel = 0;
|
const Token* const end = tok->linkAt(1);
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok->tokAt(2); tok2 != end; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "(")
|
if (tok2->varId())
|
||||||
++parlevel;
|
|
||||||
else if (tok2->str() == ")") {
|
|
||||||
if (parlevel == 0)
|
|
||||||
break;
|
|
||||||
--parlevel;
|
|
||||||
} else if (tok2->varId())
|
|
||||||
ExecutionPath::bailOutVar(checks, tok2->varId());
|
ExecutionPath::bailOutVar(checks, tok2->varId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue