From 1da0e0c229eb646b93ba8119f2b9ec4a4308ead8 Mon Sep 17 00:00:00 2001
From: chrchr-github <78114321+chrchr-github@users.noreply.github.com>
Date: Wed, 17 Jul 2024 15:36:46 +0200
Subject: [PATCH 1/3] Fix #12947 syntaxError for valid typedef (#6611)
---
lib/tokenize.cpp | 3 ++-
test/testsimplifytypedef.cpp | 13 +++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp
index 08c700794c7..cf91eabde25 100644
--- a/lib/tokenize.cpp
+++ b/lib/tokenize.cpp
@@ -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 {
diff --git a/test/testsimplifytypedef.cpp b/test/testsimplifytypedef.cpp
index 76f53b0072f..611f9fd36fd 100644
--- a/test/testsimplifytypedef.cpp
+++ b/test/testsimplifytypedef.cpp
@@ -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() {
From 3cb392dbc3f1dac8974cbc0217f64043780a8549 Mon Sep 17 00:00:00 2001
From: chrchr-github <78114321+chrchr-github@users.noreply.github.com>
Date: Wed, 17 Jul 2024 18:13:54 +0200
Subject: [PATCH 2/3] Fix #12890 FP mismatchAllocDealloc with pointer to
pointer (#6598)
---
lib/checkmemoryleak.cpp | 6 ++++--
test/testleakautovar.cpp | 42 ++++++++++++++++------------------------
2 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp
index 76aea729a55..70e578b8d21 100644
--- a/lib/checkmemoryleak.cpp
+++ b/lib/checkmemoryleak.cpp
@@ -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)
@@ -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
diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp
index 9e50ddfee9d..286c1a75c24 100644
--- a/test/testleakautovar.cpp
+++ b/test/testleakautovar.cpp
@@ -33,29 +33,7 @@ class TestLeakAutoVar : public TestFixture {
Settings settings;
void run() override {
- constexpr char xmldata[] = "\n"
- "\n"
- " \n"
- " \n"
- " malloc\n"
- " realloc\n"
- " free\n"
- " \n"
- " \n"
- " socket\n"
- " close\n"
- " \n"
- " \n"
- " fopen\n"
- " freopen\n"
- " fclose\n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "";
- settings = settingsBuilder(settings).libraryxml(xmldata, sizeof(xmldata)).build();
+ settings = settingsBuilder(settings).library("std.cfg").build();
// Assign
TEST_CASE(assign1);
@@ -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"
@@ -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() {
@@ -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"
From 5aebb2cdaf62c02db6dd1f0e8e19c9ec3806d221 Mon Sep 17 00:00:00 2001
From: chrchr-github <78114321+chrchr-github@users.noreply.github.com>
Date: Fri, 19 Jul 2024 10:22:38 +0200
Subject: [PATCH 3/3] Fix #12506 FP memleak when not calling freeaddrinfo() in
error path (#6604)
---
lib/checkleakautovar.cpp | 48 +++++++++++++++++++++++++++-------------
test/cfg/posix.c | 11 +++++++++
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp
index 80a3a862893..432b786edee 100644
--- a/lib/checkleakautovar.cpp
+++ b/lib/checkleakautovar.cpp
@@ -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 notzero,
@@ -526,6 +550,15 @@ 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& info) {
+ if (info.second.status != VarInfo::ALLOC)
+ return false;
+ const Token* ret = getReturnValueFromOutparamAlloc(info.second.allocTok, *mSettings);
+ return ret && ret->varId() && ret->varId() == vartok->varId();
+ })) {
+ varInfo1.clear();
+ }
} else if (isVarTokComparison(tok3, &vartok, alloc_failed_conds)) {
varInfo1.reallocToAlloc(vartok->varId());
varInfo1.erase(vartok->varId());
@@ -1056,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 &alloctype = varInfo.alloctype;
diff --git a/test/cfg/posix.c b/test/cfg/posix.c
index b4b8c9e4985..f135ea7d6de 100644
--- a/test/cfg/posix.c
+++ b/test/cfg/posix.c
@@ -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]