Skip to content

Commit

Permalink
Merge branch 'main' into chr_12951
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Jul 19, 2024
2 parents e6dccc1 + 5aebb2c commit 5164bef
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 44 deletions.
41 changes: 25 additions & 16 deletions lib/checkleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,30 @@ static const Token * isFunctionCall(const Token * nameToken)
return nullptr;
}

static const Token* getOutparamAllocation(const Token* tok, const Settings& settings)
{
if (!tok)
return nullptr;
int argn{};
const Token* ftok = getTokenArgumentFunction(tok, argn);
if (!ftok)
return nullptr;
if (const Library::AllocFunc* allocFunc = settings.library.getAllocFuncInfo(ftok)) {
if (allocFunc->arg == argn + 1)
return ftok;
}
return nullptr;
}

static const Token* getReturnValueFromOutparamAlloc(const Token* alloc, const Settings& settings)
{
if (const Token* ftok = getOutparamAllocation(alloc, settings)) {
if (Token::simpleMatch(ftok->astParent()->astParent(), "="))
return ftok->next()->astParent()->astOperand1();
}
return nullptr;
}

bool CheckLeakAutoVar::checkScope(const Token * const startToken,
VarInfo &varInfo,
std::set<int> notzero,
Expand Down Expand Up @@ -526,7 +550,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
if (astIsVariableComparison(tok3, "!=", "0", &vartok) &&
(notzero.find(vartok->varId()) != notzero.end()))
varInfo2.clear();

if (std::any_of(varInfo1.alloctype.begin(), varInfo1.alloctype.end(), [&](const std::pair<int, VarInfo::AllocInfo>& info) {
if (info.second.status != VarInfo::ALLOC)
return false;
Expand Down Expand Up @@ -1065,21 +1089,6 @@ void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
}
}

static const Token* getOutparamAllocation(const Token* tok, const Settings& settings)
{
if (!tok)
return nullptr;
int argn{};
const Token* ftok = getTokenArgumentFunction(tok, argn);
if (!ftok)
return nullptr;
if (const Library::AllocFunc* allocFunc = settings.library.getAllocFuncInfo(ftok)) {
if (allocFunc->arg == argn + 1)
return ftok;
}
return nullptr;
}

void CheckLeakAutoVar::ret(const Token *tok, VarInfo &varInfo, const bool isEndOfScope)
{
const std::map<int, VarInfo::AllocInfo> &alloctype = varInfo.alloctype;
Expand Down
6 changes: 4 additions & 2 deletions lib/checkmemoryleak.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
return No;
if (tok2->str() == "::")
tok2 = tok2->next();
while (Token::Match(tok2, "%name% :: %type%"))
tok2 = tok2->tokAt(2);
if (!tok2->isName())
return No;

if (!Token::Match(tok2, "%name% ::|. %type%")) {
if (!Token::Match(tok2, "%name% . %type%")) {
// Using realloc..
AllocType reallocType = getReallocationType(tok2, varid);
if (reallocType != No)
Expand Down Expand Up @@ -124,7 +126,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
}
}

while (Token::Match(tok2,"%name% ::|. %type%"))
while (Token::Match(tok2,"%name% . %type%"))
tok2 = tok2->tokAt(2);

// User function
Expand Down
3 changes: 2 additions & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,8 @@ namespace {
}

if (Token::Match(tok, "%name% ::")) {
if (Token::Match(mRangeType.first, "const| struct|class|union|enum %name% %name%|{")) {
if (Token::Match(mRangeType.first, "const| struct|class|union|enum %name% %name%|{") ||
Token::Match(mRangeType.first, "%name% %name% ;")) {
tok->originalName(tok->str());
tok->str(mRangeType.second->strAt(-1));
} else {
Expand Down
11 changes: 11 additions & 0 deletions test/cfg/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,17 @@ void memleak_getaddrinfo() // #6994
// cppcheck-suppress memleak
}

void memleak_getaddrinfo_if() // #12506
{
struct addrinfo hints = {};
struct addrinfo* addrs;
int err = getaddrinfo("example.com", "https", &hints, &addrs);
if (err != 0) {}
else {
freeaddrinfo(addrs);
}
}

void memleak_mmap(int fd)
{
// cppcheck-suppress [unusedAllocatedMemory, unreadVariable, constVariablePointer]
Expand Down
42 changes: 17 additions & 25 deletions test/testleakautovar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,7 @@ class TestLeakAutoVar : public TestFixture {
Settings settings;

void run() override {
constexpr char xmldata[] = "<?xml version=\"1.0\"?>\n"
"<def>\n"
" <podtype name=\"uint8_t\" sign=\"u\" size=\"1\"/>\n"
" <memory>\n"
" <alloc>malloc</alloc>\n"
" <realloc>realloc</realloc>\n"
" <dealloc>free</dealloc>\n"
" </memory>\n"
" <resource>\n"
" <alloc>socket</alloc>\n"
" <dealloc>close</dealloc>\n"
" </resource>\n"
" <resource>\n"
" <alloc>fopen</alloc>\n"
" <realloc realloc-arg=\"3\">freopen</realloc>\n"
" <dealloc>fclose</dealloc>\n"
" </resource>\n"
" <smart-pointer class-name=\"std::shared_ptr\"/>\n"
" <smart-pointer class-name=\"std::unique_ptr\">\n"
" <unique/>\n"
" </smart-pointer>\n"
"</def>";
settings = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build();
settings = settingsBuilder(settings).library("std.cfg").build();

// Assign
TEST_CASE(assign1);
Expand Down Expand Up @@ -462,9 +440,10 @@ class TestLeakAutoVar : public TestFixture {
}

void assign22() { // #9139
const Settings s = settingsBuilder().library("posix.cfg").build();
check("void f(char tempFileName[256]) {\n"
" const int fd = socket(AF_INET, SOCK_PACKET, 0 );\n"
"}", true);
"}", true, &s);
ASSERT_EQUALS("[test.cpp:3]: (error) Resource leak: fd\n", errout_str());

check("void f() {\n"
Expand Down Expand Up @@ -622,6 +601,19 @@ class TestLeakAutoVar : public TestFixture {
" delete[] li.front().m_p;\n"
"}\n", true);
ASSERT_EQUALS("", errout_str());

check("struct S {\n" // #12890
" int** p;\n"
" S() {\n"
" p = std::malloc(sizeof(int*));\n"
" p[0] = new int;\n"
" }\n"
" ~S() {\n"
" delete p[0];\n"
" std::free(p);\n"
" }\n"
"};\n", true);
ASSERT_EQUALS("", errout_str());
}

void assign26() {
Expand Down Expand Up @@ -652,7 +644,7 @@ class TestLeakAutoVar : public TestFixture {
check("void f() {\n"
" std::string *str = new std::string;"
"}", true);
TODO_ASSERT_EQUALS("[test.cpp:2]: (error) Memory leak: str\n", "", errout_str());
ASSERT_EQUALS("[test.cpp:2]: (error) Memory leak: str\n", errout_str());

check("class TestType {\n" // #9028
"public:\n"
Expand Down
13 changes: 13 additions & 0 deletions test/testsimplifytypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3686,6 +3686,19 @@ class TestSimplifyTypedef : public TestFixture {
"} "
"}";
ASSERT_EQUALS(exp3, tok(code3));

const char code4[] = "struct A { static const int i = 1; };\n" // #12947
"typedef A B;\n"
"int f() {\n"
" return B::i;\n"
"}\n";
const char exp4[] = "struct A { "
"static const int i = 1 ; "
"} ; "
"int f ( ) { "
"return A :: i ; "
"}";
ASSERT_EQUALS(exp4, tok(code4));
}

void simplifyTypedefFunction1() {
Expand Down

0 comments on commit 5164bef

Please sign in to comment.