diff --git a/cfg/gtk.cfg b/cfg/gtk.cfg
index ddd7ccb9b..53422ee0d 100644
--- a/cfg/gtk.cfg
+++ b/cfg/gtk.cfg
@@ -65,12 +65,8 @@
-
-
-
-
+
+
diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp
index 2984d5160..aecd93fe8 100644
--- a/lib/checkleakautovar.cpp
+++ b/lib/checkleakautovar.cpp
@@ -301,7 +301,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
}
// right ast part (after `=` operator)
- const Token* const tokRightAstOperand = tokAssignOp->astOperand2();
+ const Token* tokRightAstOperand = tokAssignOp->astOperand2();
+ while (tokRightAstOperand && tokRightAstOperand->isCast())
+ tokRightAstOperand = tokRightAstOperand->astOperand2() ? tokRightAstOperand->astOperand2() : tokRightAstOperand->astOperand1();
// is variable used in rhs?
if (isVarUsedInTree(tokRightAstOperand, varTok->varId()))
@@ -368,8 +370,12 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
if (Token::Match(innerTok, "%var% =") && innerTok->astParent() == innerTok->next()) {
// allocation?
- if (Token::Match(innerTok->tokAt(2), "%type% (")) {
- const Library::AllocFunc* f = mSettings->library.alloc(innerTok->tokAt(2));
+ // right ast part (after `=` operator)
+ const Token* tokRightAstOperand = innerTok->next()->astOperand2();
+ while (tokRightAstOperand && tokRightAstOperand->isCast())
+ tokRightAstOperand = tokRightAstOperand->astOperand2() ? tokRightAstOperand->astOperand2() : tokRightAstOperand->astOperand1();
+ if (tokRightAstOperand && Token::Match(tokRightAstOperand->previous(), "%type% (")) {
+ const Library::AllocFunc* f = mSettings->library.alloc(tokRightAstOperand->previous());
if (f && f->arg == -1) {
VarInfo::AllocInfo& varAlloc = alloctype[innerTok->varId()];
varAlloc.type = f->groupId;
diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c
index 677c6a0f2..a043f4144 100644
--- a/test/cfg/gnu.c
+++ b/test/cfg/gnu.c
@@ -79,7 +79,7 @@ void ignoreleak(void)
{
char *p = (char *)malloc(10);
__builtin_memset(&(p[0]), 0, 10);
- // TODO // cppcheck-suppress memleak
+ // cppcheck-suppress memleak
}
void memleak_asprintf(char **ptr, const char *fmt, const int arg)
diff --git a/test/cfg/gtk.c b/test/cfg/gtk.c
index 78cfc3716..7abb4991f 100644
--- a/test/cfg/gtk.c
+++ b/test/cfg/gtk.c
@@ -107,6 +107,19 @@ void g_new_test()
// cppcheck-suppress memleak
}
+void g_new_if_test()
+{
+ struct a {
+ int b;
+ };
+
+ struct a * pNew3;
+ if (pNew3 = g_new(struct a, 6)) {
+ printf("%p", pNew3);
+ }
+ // cppcheck-suppress memleak
+}
+
void g_try_new0_test()
{
struct a {
diff --git a/test/cfg/std.c b/test/cfg/std.c
index 486ce51e4..869da96fd 100644
--- a/test/cfg/std.c
+++ b/test/cfg/std.c
@@ -117,7 +117,7 @@ void ignoreleak(void)
{
char *p = (char *)malloc(10);
memset(&(p[0]), 0, 10);
- // TODO cppcheck-suppress memleak
+ // cppcheck-suppress memleak
}
// null pointer
diff --git a/test/cfg/windows.cpp b/test/cfg/windows.cpp
index c7044cd5a..5ae5cc694 100644
--- a/test/cfg/windows.cpp
+++ b/test/cfg/windows.cpp
@@ -379,7 +379,7 @@ void memleak_LocalAlloc()
(void)LocalFlags(pszBuf);
LocalLock(pszBuf);
LocalUnlock(pszBuf);
- // TODO cppcheck-suppress memleak
+ // cppcheck-suppress memleak
}
void resourceLeak_CreateSemaphoreA()
diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp
index e5efe782d..3eac62d88 100644
--- a/test/testleakautovar.cpp
+++ b/test/testleakautovar.cpp
@@ -60,6 +60,8 @@ private:
TEST_CASE(assign14);
TEST_CASE(assign15);
TEST_CASE(assign16);
+ TEST_CASE(assign17); // #9047
+ TEST_CASE(assign18);
TEST_CASE(deallocuse1);
TEST_CASE(deallocuse2);
@@ -322,6 +324,32 @@ private:
ASSERT_EQUALS("", errout.str());
}
+ void assign17() { // #9047
+ check("void f() {\n"
+ " char *p = (char*)malloc(10);\n"
+ "}");
+ ASSERT_EQUALS("[test.c:3]: (error) Memory leak: p\n", errout.str());
+
+ check("void f() {\n"
+ " char *p = (char*)(int*)malloc(10);\n"
+ "}");
+ ASSERT_EQUALS("[test.c:3]: (error) Memory leak: p\n", errout.str());
+ }
+
+ void assign18() {
+ check("void f(int x) {\n"
+ " char *p;\n"
+ " if (x && (p = (char*)malloc(10))) { }"
+ "}");
+ ASSERT_EQUALS("[test.c:3]: (error) Memory leak: p\n", errout.str());
+
+ check("void f(int x) {\n"
+ " char *p;\n"
+ " if (x && (p = (char*)(int*)malloc(10))) { }"
+ "}");
+ ASSERT_EQUALS("[test.c:3]: (error) Memory leak: p\n", errout.str());
+ }
+
void deallocuse1() {
check("void f(char *p) {\n"
" free(p);\n"