"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/checkleakautovar.cpp" between
cppcheck-1.86.tar.gz and cppcheck-1.87.tar.gz

About: Cppcheck is a static analysis tool for C/C++ code. It checks for memory leaks, mismatching allocation-deallocation, buffer overrun, and many more.

checkleakautovar.cpp  (cppcheck-1.86):checkleakautovar.cpp  (cppcheck-1.87)
/* /*
* Cppcheck - A tool for static C/C++ code analysis * Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2018 Cppcheck team. * Copyright (C) 2007-2019 Cppcheck team.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
skipping to change at line 364 skipping to change at line 364
} }
// if/else // if/else
else if (Token::simpleMatch(tok, "if (")) { else if (Token::simpleMatch(tok, "if (")) {
// Parse function calls inside the condition // Parse function calls inside the condition
const Token * closingParenthesis = tok->linkAt(1); const Token * closingParenthesis = tok->linkAt(1);
for (const Token *innerTok = tok->tokAt(2); innerTok && innerTok != closingParenthesis; innerTok = innerTok->next()) { for (const Token *innerTok = tok->tokAt(2); innerTok && innerTok != closingParenthesis; innerTok = innerTok->next()) {
// TODO: replace with checkTokenInsideExpression() // TODO: replace with checkTokenInsideExpression()
if (Token::Match(innerTok, "%var% =")) { if (Token::Match(innerTok, "%var% =") && innerTok->astParent() = = innerTok->next()) {
// allocation? // allocation?
if (Token::Match(innerTok->tokAt(2), "%type% (")) { if (Token::Match(innerTok->tokAt(2), "%type% (")) {
const Library::AllocFunc* f = mSettings->library.alloc(i nnerTok->tokAt(2)); const Library::AllocFunc* f = mSettings->library.alloc(i nnerTok->tokAt(2));
if (f && f->arg == -1) { if (f && f->arg == -1) {
VarInfo::AllocInfo& varAlloc = alloctype[innerTok->v arId()]; VarInfo::AllocInfo& varAlloc = alloctype[innerTok->v arId()];
varAlloc.type = f->groupId; varAlloc.type = f->groupId;
varAlloc.status = VarInfo::ALLOC; varAlloc.status = VarInfo::ALLOC;
} }
} else if (mTokenizer->isCPP() && Token::Match(innerTok->tok At(2), "new !!(")) { } else if (mTokenizer->isCPP() && Token::Match(innerTok->tok At(2), "new !!(")) {
const Token* tok2 = innerTok->tokAt(2)->astOperand1(); const Token* tok2 = innerTok->tokAt(2)->astOperand1();
skipping to change at line 404 skipping to change at line 404
VarInfo varInfo2(*varInfo); // VarInfo for else code VarInfo varInfo2(*varInfo); // VarInfo for else code
// Recursively scan variable comparisons in condition // Recursively scan variable comparisons in condition
std::stack<const Token *> tokens; std::stack<const Token *> tokens;
tokens.push(tok->next()->astOperand2()); tokens.push(tok->next()->astOperand2());
while (!tokens.empty()) { while (!tokens.empty()) {
const Token *tok3 = tokens.top(); const Token *tok3 = tokens.top();
tokens.pop(); tokens.pop();
if (!tok3) if (!tok3)
continue; continue;
if (tok3->str() == "&&") { if (tok3->str() == "&&" || tok3->str() == "||") {
// FIXME: handle && ! || better
tokens.push(tok3->astOperand1()); tokens.push(tok3->astOperand1());
tokens.push(tok3->astOperand2()); tokens.push(tok3->astOperand2());
continue; continue;
} }
if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) { if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) {
tokens.push(tok3->astOperand2()); tokens.push(tok3->astOperand2());
continue; continue;
} else if (tok3->str() == "(" && Token::Match(tok3->previous (), "%name%")) { } else if (tok3->str() == "(" && Token::Match(tok3->previous (), "%name%")) {
const std::vector<const Token *> params = getArguments(t ok3->previous()); const std::vector<const Token *> params = getArguments(t ok3->previous());
for (const Token *par : params) { for (const Token *par : params) {
skipping to change at line 670 skipping to change at line 671
} }
const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t ok, VarInfo *varInfo) const Token * CheckLeakAutoVar::checkTokenInsideExpression(const Token * const t ok, VarInfo *varInfo)
{ {
// Deallocation and then dereferencing pointer.. // Deallocation and then dereferencing pointer..
if (tok->varId() > 0) { if (tok->varId() > 0) {
// TODO : Write a separate checker for this that uses valueFlowForward. // TODO : Write a separate checker for this that uses valueFlowForward.
const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = v arInfo->alloctype.find(tok->varId()); const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = v arInfo->alloctype.find(tok->varId());
if (var != varInfo->alloctype.end()) { if (var != varInfo->alloctype.end()) {
bool unknown = false; bool unknown = false;
if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPo interDeRef(tok, unknown) && !unknown) { if (var->second.status == VarInfo::DEALLOC && CheckNullPointer::isPo interDeRef(tok, unknown, mSettings) && !unknown) {
deallocUseError(tok, tok->str()); deallocUseError(tok, tok->str());
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
varInfo->erase(tok->varId()); varInfo->erase(tok->varId());
} else if (tok->strAt(-1) == "=") { } else if (tok->strAt(-1) == "=") {
varInfo->erase(tok->varId()); varInfo->erase(tok->varId());
} }
} else if (Token::Match(tok->previous(), "& %name% = %var% ;")) { } else if (Token::Match(tok->previous(), "& %name% = %var% ;")) {
varInfo->referenced.insert(tok->tokAt(2)->varId()); varInfo->referenced.insert(tok->tokAt(2)->varId());
} }
} }
 End of changes. 4 change blocks. 
4 lines changed or deleted 5 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)