diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 06e5023e7..c7cc629fa 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2188,6 +2188,8 @@ void CheckMemoryLeakInFunction::checkReallocUsage() const Token *tok = _tokenizer->tokens(); while ((tok = Token::findmatch(tok, ") const| {"))) { + const Token *startOfFunction = tok; + // Record the varid's of the function parameters std::set parameterVarIds; for (tok = tok->link(); tok && tok->str() != "{"; tok = tok->next()) @@ -2213,7 +2215,9 @@ void CheckMemoryLeakInFunction::checkReallocUsage() tok->varId() == tok->tokAt(4)->varId() && parameterVarIds.find(tok->varId()) == parameterVarIds.end()) { - memleakUponReallocFailureError(tok, tok->str()); + // Check that another copy of the pointer wasn't saved earlier in the function + if (!Token::findmatch(startOfFunction, "%var% = %varid% ;", tok->varId())) + memleakUponReallocFailureError(tok, tok->str()); } } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 07058e0ec..22a25ff3a 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -330,6 +330,7 @@ private: TEST_CASE(realloc5); TEST_CASE(realloc6); TEST_CASE(realloc7); + TEST_CASE(realloc8); TEST_CASE(assign); @@ -2028,6 +2029,19 @@ private: ASSERT_EQUALS("", errout.str()); } + void realloc8() + { + check("void foo()\n" + "{\n" + " char *origBuf = m_buf;\n" + " m_buf = (char *) realloc (m_buf, m_capacity + growBy);\n" + " if (!m_buf) {\n" + " m_buf = origBuf;\n" + " }\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("void foo()\n"