/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2016 Cppcheck team.
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
//---------------------------------------------------------------------------
// Leaks when using auto variables
//---------------------------------------------------------------------------
#include "checkleakautovar.h"
#include "astutils.h"
#include "checkmemoryleak.h" // <- CheckMemoryLeak::memoryLeak
#include "checknullpointer.h" // <- CheckNullPointer::isPointerDeRef
#include "errorlogger.h"
#include "mathlib.h"
#include "settings.h"
#include "symboldatabase.h"
#include "token.h"
#include "tokenize.h"
#include "valueflow.h"
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
// Register this check class (by creating a static instance of it)
namespace {
CheckLeakAutoVar instance;
}
static const CWE CWE672(672U);
static const CWE CWE415(415U);
//---------------------------------------------------------------------------
void VarInfo::print()
{
std::cout << "size=" << alloctype.size() << std::endl;
std::map::const_iterator it;
for (it = alloctype.begin(); it != alloctype.end(); ++it) {
std::string strusage;
std::map::const_iterator use = possibleUsage.find(it->first);
if (use != possibleUsage.end())
strusage = use->second;
std::string status;
switch (it->second.status) {
case DEALLOC:
status = "dealloc";
break;
case ALLOC:
status = "alloc";
break;
case NOALLOC:
status = "noalloc";
break;
default:
status = "?";
break;
};
std::cout << "status=" << status << " "
<< "alloctype='" << it->second.type << "' "
<< "possibleUsage='" << strusage << "' "
<< "conditionalAlloc=" << (conditionalAlloc.find(it->first) != conditionalAlloc.end() ? "yes" : "no") << " "
<< "referenced=" << (referenced.find(it->first) != referenced.end() ? "yes" : "no") << " "
<< std::endl;
}
}
void VarInfo::possibleUsageAll(const std::string &functionName)
{
possibleUsage.clear();
std::map::const_iterator it;
for (it = alloctype.begin(); it != alloctype.end(); ++it)
possibleUsage[it->first] = functionName;
}
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type)
{
const CheckMemoryLeak checkmemleak(_tokenizer, _errorLogger, _settings);
if (_settings->library.isresource(type))
checkmemleak.resourceLeakError(tok, varname);
else
checkmemleak.memleakError(tok, varname);
}
void CheckLeakAutoVar::mismatchError(const Token *tok, const std::string &varname)
{
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings);
std::list callstack(1, tok);
c.mismatchAllocDealloc(callstack, varname);
}
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
{
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings);
c.deallocuseError(tok, varname);
}
void CheckLeakAutoVar::deallocReturnError(const Token *tok, const std::string &varname)
{
reportError(tok, Severity::error, "deallocret", "Returning/dereferencing '" + varname + "' after it is deallocated / released", CWE672, false);
}
void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &functionName)
{
if (_settings->checkLibrary && _settings->isEnabled(Settings::INFORMATION)) {
reportError(tok,
Severity::information,
"checkLibraryUseIgnore",
"--check-library: Function " + functionName + "() should have