- Solved FIXME: Made detection of code that is no pointer-dereference more robust, uncommented code (checknullpointer.cpp)

- Removed more indendation level counters
- Make use of symbol database more often
- Other refactorizations
This commit is contained in:
PKEuS 2012-01-21 19:55:32 +01:00
parent 87e19d2552
commit 36479499e7
6 changed files with 204 additions and 237 deletions

View File

@ -119,16 +119,18 @@ void CheckInternal::checkTokenSimpleMatchPatterns()
void CheckInternal::checkMissingPercentCharacter() void CheckInternal::checkMissingPercentCharacter()
{ {
std::set<std::string> magics; static std::set<std::string> magics;
magics.insert("%any%"); if (magics.empty()) {
magics.insert("%var%"); magics.insert("%any%");
magics.insert("%type%"); magics.insert("%var%");
magics.insert("%num%"); magics.insert("%type%");
magics.insert("%bool%"); magics.insert("%num%");
magics.insert("%str%"); magics.insert("%bool%");
magics.insert("%varid%"); magics.insert("%str%");
magics.insert("%or%"); magics.insert("%varid%");
magics.insert("%oror%"); magics.insert("%or%");
magics.insert("%oror%");
}
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "Token :: Match (") && !Token::simpleMatch(tok, "Token :: findmatch (")) if (!Token::simpleMatch(tok, "Token :: Match (") && !Token::simpleMatch(tok, "Token :: findmatch ("))

View File

@ -37,7 +37,7 @@ namespace {
bool CheckNullPointer::isUpper(const std::string &str) bool CheckNullPointer::isUpper(const std::string &str)
{ {
for (unsigned int i = 0; i < str.length(); ++i) { for (unsigned int i = 0; i < str.length(); ++i) {
if (str[i] >= 'a' && str[i] <= 'z') if (std::islower(str[i]))
return false; return false;
} }
return true; return true;
@ -234,10 +234,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
return false; return false;
} }
if (Token::Match(tok->previous(), "[;{}=+-/(,] %var% [")) if (Token::Match(tok->previous(), "!!& %var% ["))
return true;
if (Token::Match(tok->previous(), "return %var% ["))
return true; return true;
if (Token::Match(tok, "%var% (")) if (Token::Match(tok, "%var% ("))
@ -252,7 +249,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
// This is most useful in inconclusive checking // This is most useful in inconclusive checking
if (inconclusive) { if (inconclusive) {
// Not a dereference.. // Not a dereference..
if (Token::Match(tok->previous(), "[;{}(] %var% =")) if (Token::Match(tok, "%var% ="))
return false; return false;
// OK to delete a null // OK to delete a null
@ -261,7 +258,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
// OK to check if pointer is null // OK to check if pointer is null
// OK to take address of pointer // OK to take address of pointer
if (Token::Match(tok->previous(), "!|& %var% )|,|&&|%oror%")) if (Token::Match(tok->previous(), "!|& %var%"))
return false; return false;
// OK to pass pointer to function // OK to pass pointer to function
@ -269,7 +266,9 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
return false; return false;
// Compare pointer // Compare pointer
if (Token::Match(tok->previous(), "(|&&|%oror%|==|!= %var% &&|%oror%|)")) if (Token::Match(tok->previous(), "(|&&|%oror%|==|!= %var%"))
return false;
if (Token::Match(tok, "%var% &&|%oror%|==|!=|)"))
return false; return false;
// Taking address // Taking address
@ -277,11 +276,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
return false; return false;
// unknown if it's a dereference // unknown if it's a dereference
// FIXME: Uncomment this. We just need to fix false positives unknown = true;
// when cppcheck source code is checked before it can
// be uncommented. We need to have better checks to
// determine when there is NOT a pointer dereference.
//unknown = true;
} }
// assume that it's not a dereference (no false positives) // assume that it's not a dereference (no false positives)
@ -292,7 +287,7 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
// check if function can assign pointer // check if function can assign pointer
bool CheckNullPointer::CanFunctionAssignPointer(const Token *functiontoken, unsigned int varid) const bool CheckNullPointer::CanFunctionAssignPointer(const Token *functiontoken, unsigned int varid) const
{ {
if (Token::Match(functiontoken, "if|while|sizeof")) if (Token::Match(functiontoken, "if|while|for|switch|sizeof|catch"))
return false; return false;
int argumentNumber = 0; int argumentNumber = 0;
@ -434,7 +429,7 @@ void CheckNullPointer::nullPointerLinkedList()
const std::string varname(tok2->str()); const std::string varname(tok2->str());
// Check usage of dereferenced variable in the loop.. // Check usage of dereferenced variable in the loop..
for (const Token *tok3 = i->classStart; tok3 && tok3 != i->classEnd; tok3 = tok3->next()) { for (const Token *tok3 = i->classStart->next(); tok3 && tok3 != i->classEnd; tok3 = tok3->next()) {
// TODO: are there false negatives for "while ( %varid% ||" // TODO: are there false negatives for "while ( %varid% ||"
if (Token::Match(tok3, "while ( %varid% &&|)", varid)) { if (Token::Match(tok3, "while ( %varid% &&|)", varid)) {
// Make sure there is a "break" or "return" inside the loop. // Make sure there is a "break" or "return" inside the loop.
@ -801,174 +796,167 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
void CheckNullPointer::nullPointerByCheckAndDeRef() void CheckNullPointer::nullPointerByCheckAndDeRef()
{ {
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
// Check if pointer is NULL and then dereference it.. // Check if pointer is NULL and then dereference it..
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
if (i->type != Scope::eIf && i->type != Scope::eElseIf && i->type != Scope::eWhile)
continue;
if (!i->classDef || i->classDef->isExpandedMacro())
continue;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { const Token* const tok = i->type != Scope::eElseIf ? i->classDef : i->classDef->next();
if (Token::simpleMatch(tok, "if (") && !tok->isExpandedMacro()) { // TODO: investigate false negatives:
// TODO: investigate false negatives: // - handle "while"?
// - handle "while"? // - if there are logical operators
// - if there are logical operators // - if (x) { } else { ... }
// - if (x) { } else { ... }
// If the if-body ends with a unknown macro then bailout // If the if-body ends with a unknown macro then bailout
{ if (Token::Match(i->classEnd->tokAt(-3), "[;{}] %var% ;") && isUpper(i->classEnd->strAt(-2)))
// goto the end parenthesis continue;
const Token *endpar = tok->next()->link();
const Token *endbody = Token::simpleMatch(endpar, ") {") ? endpar->next()->link() : 0;
if (endbody &&
Token::Match(endbody->tokAt(-3), "[;{}] %var% ;") &&
isUpper(endbody->strAt(-2)))
continue;
}
// vartok : token for the variable // vartok : token for the variable
const Token *vartok = 0; const Token *vartok = 0;
if (Token::Match(tok, "if ( ! %var% )|&&")) if (Token::Match(tok, "if ( ! %var% )|&&"))
vartok = tok->tokAt(3); vartok = tok->tokAt(3);
else if (Token::Match(tok, "if|while ( %var% )|&&")) else if (Token::Match(tok, "if|while ( %var% )|&&"))
vartok = tok->tokAt(2); vartok = tok->tokAt(2);
else if (Token::Match(tok, "if ( ! ( %var% =")) else if (Token::Match(tok, "if ( ! ( %var% ="))
vartok = tok->tokAt(4); vartok = tok->tokAt(4);
else else
continue;
// variable id for pointer
const unsigned int varid(vartok->varId());
if (varid == 0)
continue;
const unsigned int linenr = vartok->linenr();
const Variable* var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varid);
// Check if variable is a pointer
if (!var || !var->isPointer())
continue;
if (Token::Match(vartok->next(), "&& ( %varid% =", varid))
continue;
// if this is true then it is known that the pointer is null
bool null = true;
// start token = inside the if-body
const Token *tok1 = i->classStart;
if (Token::Match(tok, "if|while ( %var% )|&&")) {
// pointer might be null
null = false;
// start token = first token after the if/while body
tok1 = i->classEnd->next();
if (!tok1)
continue; continue;
}
// variable id for pointer unsigned int indentlevel = 0;
const unsigned int varid(vartok->varId());
if (varid == 0)
continue;
const unsigned int linenr = vartok->linenr(); // Name of the pointer
const std::string &pointerName = vartok->str();
const Variable* var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varid); // Set to true if we would normally bail out the check.
// Check if variable is a pointer bool inconclusive = false;
if (!var || !var->isPointer())
continue;
if (Token::Match(vartok->next(), "&& ( %varid% =", varid)) // Count { and } for tok2
continue; for (const Token *tok2 = tok1; tok2; tok2 = tok2->next()) {
if (tok2->str() == "{")
// if this is true then it is known that the pointer is null ++indentlevel;
bool null = true; else if (tok2->str() == "}") {
if (indentlevel == 0)
// start token = inside the if-body
const Token *tok1 = tok->next()->link()->tokAt(2);
// indentlevel inside the if-body is 1
unsigned int indentlevel = 1;
if (Token::Match(tok, "if|while ( %var% )|&&")) {
// pointer might be null
null = false;
// start token = first token after the if/while body
tok1 = tok1->previous()->link();
tok1 = tok1 ? tok1->next() : NULL;
if (!tok1)
continue;
// indentlevel at the base level is 0
indentlevel = 0;
}
// Name of the pointer
const std::string &pointerName = vartok->str();
// Set to true if we would normally bail out the check.
bool inconclusive = false;
// Count { and } for tok2
for (const Token *tok2 = tok1; tok2; tok2 = tok2->next()) {
if (tok2->str() == "{")
++indentlevel;
else if (tok2->str() == "}") {
if (indentlevel == 0)
break;
--indentlevel;
// calling exit function?
bool unknown = false;
if (_tokenizer->IsScopeNoReturn(tok2, &unknown)) {
if (_settings->inconclusive && unknown)
inconclusive = true;
else
break;
}
if (null && indentlevel == 0) {
// skip all "else" blocks because they are not executed in this execution path
while (Token::simpleMatch(tok2, "} else {"))
tok2 = tok2->linkAt(2);
null = false;
}
}
if (Token::Match(tok2, "goto|return|continue|break|throw|if|switch|for")) {
bool dummy = false;
if (Token::Match(tok2, "return * %varid%", varid))
nullPointerError(tok2, pointerName, linenr, inconclusive);
else if (Token::Match(tok2, "return %varid%", varid) &&
CheckNullPointer::isPointerDeRef(tok2->next(), dummy))
nullPointerError(tok2, pointerName, linenr, inconclusive);
break; break;
} --indentlevel;
// parameters to sizeof are not dereferenced // calling exit function?
if (Token::Match(tok2, "decltype|sizeof")) { bool unknown = false;
if (tok2->strAt(1) != "(") if (_tokenizer->IsScopeNoReturn(tok2, &unknown)) {
break; if (_settings->inconclusive && unknown)
tok2 = tok2->next()->link();
continue;
}
// function call, check if pointer is dereferenced
if (Token::Match(tok2, "%var% (")) {
std::list<const Token *> vars;
parseFunctionCall(*tok2, vars, 0);
for (std::list<const Token *>::const_iterator it = vars.begin(); it != vars.end(); ++it) {
if (Token::Match(*it, "%varid% [,)]", varid)) {
nullPointerError(*it, pointerName, linenr, inconclusive);
break;
}
}
}
// calling unknown function (abort/init)..
if (Token::simpleMatch(tok2, ") ;") &&
(Token::Match(tok2->link()->tokAt(-2), "[;{}.] %var% (") ||
Token::Match(tok2->link()->tokAt(-5), "[;{}] ( * %var% ) ("))) {
// noreturn function?
bool unknown = false;
if (_tokenizer->IsScopeNoReturn(tok2->tokAt(2), &unknown)) {
if (!unknown || !_settings->inconclusive) {
break;
}
inconclusive = true; inconclusive = true;
}
// init function (global variables)
if (!var || !(var->isLocal() || var->isArgument()))
break;
}
if (tok2->varId() == varid) {
// unknown: this is set to true by isPointerDeRef if
// the function fails to determine if there
// is a dereference or not
bool unknown = _settings->inconclusive;
if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;"))
;
else if (CheckNullPointer::isPointerDeRef(tok2, unknown))
nullPointerError(tok2, pointerName, linenr, inconclusive);
else if (unknown && _settings->inconclusive)
nullPointerError(tok2, pointerName, linenr, true);
else else
break; break;
} }
if (null && indentlevel == 0) {
// skip all "else" blocks because they are not executed in this execution path
while (Token::simpleMatch(tok2, "} else {"))
tok2 = tok2->linkAt(2);
null = false;
}
}
if (Token::Match(tok2, "goto|return|continue|break|throw|if|switch|for")) {
bool dummy = false;
if (Token::Match(tok2, "return * %varid%", varid))
nullPointerError(tok2, pointerName, linenr, inconclusive);
else if (Token::Match(tok2, "return %varid%", varid) &&
CheckNullPointer::isPointerDeRef(tok2->next(), dummy))
nullPointerError(tok2, pointerName, linenr, inconclusive);
break;
}
// parameters to sizeof are not dereferenced
if (Token::Match(tok2, "decltype|sizeof")) {
if (tok2->strAt(1) != "(")
break;
tok2 = tok2->next()->link();
continue;
}
// function call, check if pointer is dereferenced
if (Token::Match(tok2, "%var% (")) {
std::list<const Token *> vars;
parseFunctionCall(*tok2, vars, 0);
for (std::list<const Token *>::const_iterator it = vars.begin(); it != vars.end(); ++it) {
if (Token::Match(*it, "%varid% [,)]", varid)) {
nullPointerError(*it, pointerName, linenr, inconclusive);
break;
}
}
}
// calling unknown function (abort/init)..
if (Token::simpleMatch(tok2, ") ;") &&
(Token::Match(tok2->link()->tokAt(-2), "[;{}.] %var% (") ||
Token::Match(tok2->link()->tokAt(-5), "[;{}] ( * %var% ) ("))) {
// noreturn function?
bool unknown = false;
if (_tokenizer->IsScopeNoReturn(tok2->tokAt(2), &unknown)) {
if (!unknown || !_settings->inconclusive) {
break;
}
inconclusive = true;
}
// init function (global variables)
if (!var || !(var->isLocal() || var->isArgument()))
break;
}
if (tok2->varId() == varid) {
// unknown: this is set to true by isPointerDeRef if
// the function fails to determine if there
// is a dereference or not
bool unknown = _settings->inconclusive;
if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;"))
;
else if (CheckNullPointer::isPointerDeRef(tok2, unknown))
nullPointerError(tok2, pointerName, linenr, inconclusive);
else if (unknown && _settings->inconclusive)
nullPointerError(tok2, pointerName, linenr, true);
else
break;
} }
} }
} }
@ -987,25 +975,13 @@ void CheckNullPointer::nullPointer()
/** Dereferencing null constant (simplified token list) */ /** Dereferencing null constant (simplified token list) */
void CheckNullPointer::nullConstantDereference() void CheckNullPointer::nullConstantDereference()
{ {
// this is kept at 0 for all scopes that are not executing const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
unsigned int indentlevel = 0;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
// start of executable scope.. if (i->type != Scope::eFunction || !i->classStart)
if (indentlevel == 0 && Token::Match(tok, ") const| {")) continue;
indentlevel = 1;
else if (indentlevel >= 1) {
if (tok->str() == "{")
++indentlevel;
else if (tok->str() == "}") {
if (indentlevel <= 2)
indentlevel = 0;
else
--indentlevel;
}
for (const Token *tok = i->classStart; tok != i->classEnd; tok = tok->next()) {
if (tok->str() == "(" && Token::Match(tok->previous(), "sizeof|decltype|typeid")) if (tok->str() == "(" && Token::Match(tok->previous(), "sizeof|decltype|typeid"))
tok = tok->link(); tok = tok->link();
@ -1015,7 +991,7 @@ void CheckNullPointer::nullConstantDereference()
} }
} }
else if (indentlevel > 0 && Token::Match(tok->previous(), "[={};] %var% (")) { else if (Token::Match(tok->previous(), "[={};] %var% (")) {
std::list<const Token *> var; std::list<const Token *> var;
parseFunctionCall(*tok, var, 0); parseFunctionCall(*tok, var, 0);

View File

@ -599,8 +599,7 @@ void CheckOther::checkSwitchCaseFallThrough()
const char breakPattern[] = "break|continue|return|exit|goto|throw"; const char breakPattern[] = "break|continue|return|exit|goto|throw";
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) { for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
const Token* const tok = i->classDef; if (i->type != Scope::eSwitch || !i->classStart) // Find the beginning of a switch
if (i->type != Scope::eSwitch || !tok) // Find the beginning of a switch
continue; continue;
// Check the contents of the switch statement // Check the contents of the switch statement
@ -609,7 +608,7 @@ void CheckOther::checkSwitchCaseFallThrough()
std::stack<Token *> scopenest; std::stack<Token *> scopenest;
bool justbreak = true; bool justbreak = true;
bool firstcase = true; bool firstcase = true;
for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next()) { for (const Token *tok2 = i->classStart; tok2 != i->classEnd; tok2 = tok2->next()) {
if (Token::simpleMatch(tok2, "if (")) { if (Token::simpleMatch(tok2, "if (")) {
tok2 = tok2->next()->link()->next(); tok2 = tok2->next()->link()->next();
if (tok2->link() == NULL) { if (tok2->link() == NULL) {
@ -827,11 +826,11 @@ void CheckOther::checkAssignmentInAssert()
const Token *endTok = tok ? tok->next()->link() : NULL; const Token *endTok = tok ? tok->next()->link() : NULL;
while (tok && endTok) { while (tok && endTok) {
const Token* varTok = Token::findmatch(tok->tokAt(2), "%var% --|++|+=|-=|*=|/=|&=|^=|=", endTok); for (tok = tok->tokAt(2); tok != endTok; tok = tok->next()) {
if (varTok) { if (tok->isName() && (tok->next()->isAssignmentOp() || tok->next()->str() == "++" || tok->next()->str() == "--"))
assignmentInAssertError(tok, varTok->str()); assignmentInAssertError(tok, tok->str());
} else if (NULL != (varTok = Token::findmatch(tok->tokAt(2), "--|++ %var%", endTok))) { else if (Token::Match(tok, "--|++ %var%"))
assignmentInAssertError(tok, varTok->strAt(1)); assignmentInAssertError(tok, tok->strAt(1));
} }
tok = Token::findmatch(endTok->next(), assertPattern); tok = Token::findmatch(endTok->next(), assertPattern);
@ -1638,7 +1637,7 @@ void CheckOther::checkUnreachableCode()
// that the goto jump was intended to skip some code on the first loop iteration. // that the goto jump was intended to skip some code on the first loop iteration.
bool labelInFollowingLoop = false; bool labelInFollowingLoop = false;
if (labelName && Token::Match(secondBreak, "while|do|for")) { if (labelName && Token::Match(secondBreak, "while|do|for")) {
const Token *scope = Token::findmatch(secondBreak, "{"); const Token *scope = Token::findsimplematch(secondBreak, "{");
if (scope) { if (scope) {
for (const Token *tokIter = scope; tokIter != scope->link() && tokIter; tokIter = tokIter->next()) { for (const Token *tokIter = scope; tokIter != scope->link() && tokIter; tokIter = tokIter->next()) {
if (Token::Match(tokIter, "[;{}] %any% :") && labelName->str() == tokIter->strAt(1)) { if (Token::Match(tokIter, "[;{}] %any% :") && labelName->str() == tokIter->strAt(1)) {
@ -2270,24 +2269,12 @@ void CheckOther::checkMisusedScopedObject()
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope>::const_iterator scope; for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check functions // only check functions
if (scope->type != Scope::eFunction) if (scope->type != Scope::eFunction)
continue; continue;
unsigned int depth = 0; for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
for (const Token *tok = scope->classStart; tok; tok = tok->next()) {
if (tok->str() == "{") {
++depth;
} else if (tok->str() == "}") {
if (depth <= 1)
break;
--depth;
}
if (Token::Match(tok, "[;{}] %var% (") if (Token::Match(tok, "[;{}] %var% (")
&& Token::simpleMatch(tok->linkAt(2), ") ;") && Token::simpleMatch(tok->linkAt(2), ") ;")
&& symbolDatabase->isClassOrStruct(tok->next()->str()) && symbolDatabase->isClassOrStruct(tok->next()->str())
@ -2484,15 +2471,15 @@ void CheckOther::checkDuplicateBranch()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CheckOther::checkDoubleFree() void CheckOther::checkDoubleFree()
{ {
std::set<int> freedVariables; std::set<unsigned int> freedVariables;
std::set<int> closeDirVariables; std::set<unsigned int> closeDirVariables;
for (const Token* tok = _tokenizer->tokens(); tok; tok = tok->next()) { for (const Token* tok = _tokenizer->tokens(); tok; tok = tok->next()) {
// Keep track of any variables passed to "free()", "g_free()" or "closedir()", // Keep track of any variables passed to "free()", "g_free()" or "closedir()",
// and report an error if the same variable is passed twice. // and report an error if the same variable is passed twice.
if (Token::Match(tok, "free|g_free|closedir ( %var% )")) { if (Token::Match(tok, "free|g_free|closedir ( %var% )")) {
int var = tok->tokAt(2)->varId(); unsigned int var = tok->tokAt(2)->varId();
if (var) { if (var) {
if (Token::Match(tok, "free|g_free")) { if (Token::Match(tok, "free|g_free")) {
if (freedVariables.find(var) != freedVariables.end()) if (freedVariables.find(var) != freedVariables.end())
@ -2512,7 +2499,7 @@ void CheckOther::checkDoubleFree()
// and report an error if the same variable is delete'd twice. // and report an error if the same variable is delete'd twice.
else if (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")) { else if (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")) {
int varIdx = (tok->strAt(1) == "[") ? 3 : 1; int varIdx = (tok->strAt(1) == "[") ? 3 : 1;
int var = tok->tokAt(varIdx)->varId(); unsigned int var = tok->tokAt(varIdx)->varId();
if (var) { if (var) {
if (freedVariables.find(var) != freedVariables.end()) if (freedVariables.find(var) != freedVariables.end())
doubleFreeError(tok, tok->tokAt(varIdx)->str()); doubleFreeError(tok, tok->tokAt(varIdx)->str());
@ -2531,7 +2518,7 @@ void CheckOther::checkDoubleFree()
else if (Token::Match(tok, "%var% (") && !Token::Match(tok, "printf|sprintf|snprintf|fprintf")) { else if (Token::Match(tok, "%var% (") && !Token::Match(tok, "printf|sprintf|snprintf|fprintf")) {
for (const Token* tok2 = tok->tokAt(2); tok2 != tok->linkAt(1); tok2 = tok2->next()) { for (const Token* tok2 = tok->tokAt(2); tok2 != tok->linkAt(1); tok2 = tok2->next()) {
if (Token::Match(tok2, "%var%")) { if (Token::Match(tok2, "%var%")) {
int var = tok2->varId(); unsigned int var = tok2->varId();
if (var) { if (var) {
freedVariables.erase(var); freedVariables.erase(var);
closeDirVariables.erase(var); closeDirVariables.erase(var);
@ -2542,7 +2529,7 @@ void CheckOther::checkDoubleFree()
// If a pointer is assigned a new value, remove it from the set of previously freed variables // If a pointer is assigned a new value, remove it from the set of previously freed variables
else if (Token::Match(tok, "%var% =")) { else if (Token::Match(tok, "%var% =")) {
int var = tok->varId(); unsigned int var = tok->varId();
if (var) { if (var) {
freedVariables.erase(var); freedVariables.erase(var);
closeDirVariables.erase(var); closeDirVariables.erase(var);

View File

@ -79,16 +79,18 @@ std::string Settings::addEnabled(const std::string &str)
bool handled = false; bool handled = false;
std::set<std::string> id; static std::set<std::string> id;
id.insert("style"); if (id.empty()) {
id.insert("performance"); id.insert("style");
id.insert("portability"); id.insert("performance");
id.insert("information"); id.insert("portability");
id.insert("missingInclude"); id.insert("information");
id.insert("unusedFunction"); id.insert("missingInclude");
id.insert("unusedFunction");
#ifndef NDEBUG #ifndef NDEBUG
id.insert("internal"); id.insert("internal");
#endif #endif
}
if (str == "all") { if (str == "all") {
std::set<std::string>::const_iterator it; std::set<std::string>::const_iterator it;

View File

@ -83,15 +83,15 @@ const Token* TemplateSimplifier::hasComplicatedSyntaxErrorsInTemplates(Token *to
} }
// skip executing scopes (ticket #1984).. // skip executing scopes (ticket #1984)..
if (Token::simpleMatch(tok, "; {")) else if (Token::simpleMatch(tok, "; {"))
tok = tok->next()->link(); tok = tok->next()->link();
// skip executing scopes (ticket #3183).. // skip executing scopes (ticket #3183)..
if (Token::simpleMatch(tok, "( {")) else if (Token::simpleMatch(tok, "( {"))
tok = tok->next()->link(); tok = tok->next()->link();
// skip executing scopes (ticket #1985).. // skip executing scopes (ticket #1985)..
if (Token::simpleMatch(tok, "try {")) { else if (Token::simpleMatch(tok, "try {")) {
tok = tok->next()->link(); tok = tok->next()->link();
while (Token::simpleMatch(tok, "} catch (")) { while (Token::simpleMatch(tok, "} catch (")) {
tok = tok->linkAt(2); tok = tok->linkAt(2);

View File

@ -2392,7 +2392,7 @@ bool Tokenizer::hasEnumsWithTypedef()
for (const Token *tok = _tokens; tok; tok = tok->next()) { for (const Token *tok = _tokens; tok; tok = tok->next()) {
if (Token::Match(tok, "enum %var% {")) { if (Token::Match(tok, "enum %var% {")) {
tok = tok->tokAt(2); tok = tok->tokAt(2);
const Token *tok2 = Token::findmatch(tok, "typedef", tok->link()); const Token *tok2 = Token::findsimplematch(tok, "typedef", tok->link());
if (tok2) { if (tok2) {
syntaxError(tok2); syntaxError(tok2);
return true; return true;