memory leaks: Made leak checking inconclusive instead of experimental

This commit is contained in:
Daniel Marjamäki 2011-11-25 14:47:45 +01:00
parent 7c4c0b628b
commit 50c320ef27
3 changed files with 134 additions and 101 deletions

View File

@ -33,8 +33,7 @@
// Register this check class (by creating a static instance of it) // Register this check class (by creating a static instance of it)
namespace { namespace {
// Experimental (#3267 and #3268) CheckMemoryLeakInFunction instance1;
// CheckMemoryLeakInFunction instance1;
CheckMemoryLeakInClass instance2; CheckMemoryLeakInClass instance2;
CheckMemoryLeakStructMember instance3; CheckMemoryLeakStructMember instance3;
CheckMemoryLeakNoVar instance4; CheckMemoryLeakNoVar instance4;
@ -309,15 +308,15 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void CheckMemoryLeak::memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype) void CheckMemoryLeak::memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype, bool inconclusive)
{ {
if (alloctype == CheckMemoryLeak::File || if (alloctype == CheckMemoryLeak::File ||
alloctype == CheckMemoryLeak::Pipe || alloctype == CheckMemoryLeak::Pipe ||
alloctype == CheckMemoryLeak::Fd || alloctype == CheckMemoryLeak::Fd ||
alloctype == CheckMemoryLeak::Dir) alloctype == CheckMemoryLeak::Dir)
resourceLeakError(tok, varname.c_str()); resourceLeakError(tok, varname.c_str(), inconclusive);
else else
memleakError(tok, varname.c_str()); memleakError(tok, varname.c_str(), inconclusive);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -354,9 +353,31 @@ void CheckMemoryLeak::reportErr(const std::list<const Token *> &callstack, Sever
Check::reportError(errmsg); Check::reportError(errmsg);
} }
void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname) void CheckMemoryLeak::reportInconclusiveError(const Token *tok, Severity::SeverityType severity, const std::string &id, const std::string &msg) const
{ {
reportErr(tok, Severity::error, "memleak", "Memory leak: " + varname); std::list<ErrorLogger::ErrorMessage::FileLocation> locations;
if (tok) {
ErrorLogger::ErrorMessage::FileLocation loc;
loc.line = tok->linenr();
loc.setfile(tokenizer->file(tok));
locations.push_back(loc);
}
const ErrorLogger::ErrorMessage errmsg(locations, severity, msg, id, true);
if (errorLogger)
errorLogger->reportErr(errmsg);
else
Check::reportError(errmsg);
}
void CheckMemoryLeak::memleakError(const Token *tok, const std::string &varname, bool inconclusive)
{
if (inconclusive)
reportInconclusiveError(tok, Severity::error, "memleak", "Memory leak: " + varname + " (this might be a false warning)");
else
reportErr(tok, Severity::error, "memleak", "Memory leak: " + varname);
} }
void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &varname) void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std::string &varname)
@ -364,12 +385,15 @@ void CheckMemoryLeak::memleakUponReallocFailureError(const Token *tok, const std
reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \'" + varname + "\' nulled but not freed upon failure"); reportErr(tok, Severity::error, "memleakOnRealloc", "Common realloc mistake: \'" + varname + "\' nulled but not freed upon failure");
} }
void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname) void CheckMemoryLeak::resourceLeakError(const Token *tok, const std::string &varname, bool inconclusive)
{ {
std::string errmsg("Resource leak"); std::string errmsg("Resource leak");
if (!varname.empty()) if (!varname.empty())
errmsg += ": " + varname; errmsg += ": " + varname;
reportErr(tok, Severity::error, "resourceLeak", errmsg); if (inconclusive)
reportInconclusiveError(tok, Severity::error, "resourceLeak", errmsg + " (this might be a false warning)");
else
reportErr(tok, Severity::error, "resourceLeak", errmsg);
} }
void CheckMemoryLeak::deallocDeallocError(const Token *tok, const std::string &varname) void CheckMemoryLeak::deallocDeallocError(const Token *tok, const std::string &varname)
@ -2175,7 +2199,7 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string
} }
if ((result = findleak(tok)) != NULL) { if ((result = findleak(tok)) != NULL) {
memoryLeak(result, varname, alloctype); memoryLeak(result, varname, alloctype, true);
} }
else if ((result = Token::findsimplematch(tok, "dealloc ; dealloc ;")) != NULL) { else if ((result = Token::findsimplematch(tok, "dealloc ; dealloc ;")) != NULL) {
@ -2379,8 +2403,8 @@ void CheckMemoryLeakInFunction::parseFunctionScope(const Token *tok, const Token
void CheckMemoryLeakInFunction::check() void CheckMemoryLeakInFunction::check()
{ {
// experimental checks. See #3267 and #3268 // inconclusive checks. See #3267 and #3268
if (!_settings->experimental) if (!_settings->inconclusive)
return; return;
// fill the "noreturn" // fill the "noreturn"
@ -2582,9 +2606,9 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam
} }
if (allocInConstructor && !deallocInDestructor) { if (allocInConstructor && !deallocInDestructor) {
memoryLeak(tokVarname, (classname + "::" + varname).c_str(), Alloc); memoryLeak(tokVarname, (classname + "::" + varname).c_str(), Alloc, false);
} else if (Alloc != CheckMemoryLeak::No && Dealloc == CheckMemoryLeak::No) { } else if (Alloc != CheckMemoryLeak::No && Dealloc == CheckMemoryLeak::No) {
memoryLeak(tokVarname, (classname + "::" + varname).c_str(), Alloc); memoryLeak(tokVarname, (classname + "::" + varname).c_str(), Alloc, false);
} }
} }
@ -2727,7 +2751,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Token * const vartok
else if (tok3->str() == "}") { else if (tok3->str() == "}") {
if (indentlevel3 == 0) { if (indentlevel3 == 0) {
memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc); memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc, false);
break; break;
} }
--indentlevel3; --indentlevel3;
@ -2759,7 +2783,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Token * const vartok
// Deallocating the struct.. // Deallocating the struct..
else if (indentlevel2 == 0 && Token::Match(tok3, "free|kfree ( %varid% )", structid)) { else if (indentlevel2 == 0 && Token::Match(tok3, "free|kfree ( %varid% )", structid)) {
memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc); memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc, false);
break; break;
} }
@ -2805,7 +2829,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Token * const vartok
// Returning from function without deallocating struct member? // Returning from function without deallocating struct member?
if (!Token::Match(tok3, "return %varid% ;", structid) && if (!Token::Match(tok3, "return %varid% ;", structid) &&
!Token::Match(tok3, "return & %varid% .", structid)) { !Token::Match(tok3, "return & %varid% .", structid)) {
memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc); memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc, false);
} }
break; break;
} }

View File

@ -82,6 +82,15 @@ private:
*/ */
void reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) const; void reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) const;
/**
* Report inconclusive error. Similar with the function Check::reportInconclusiveError
* @param location the token where the error occurs
* @param severity the severity of the bug
* @param id type of message
* @param msg text
*/
void reportInconclusiveError(const Token *location, Severity::SeverityType severity, const std::string &id, const std::string &msg) const;
public: public:
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e) CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e)
: tokenizer(t), errorLogger(e) { : tokenizer(t), errorLogger(e) {
@ -91,7 +100,7 @@ public:
/** @brief What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */ /** @brief What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */
enum AllocType { No, Malloc, gMalloc, New, NewArray, File, Fd, Pipe, Dir, Many }; enum AllocType { No, Malloc, gMalloc, New, NewArray, File, Fd, Pipe, Dir, Many };
void memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype); void memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype, bool inconclusive);
/** /**
* @brief Get type of deallocation at given position * @brief Get type of deallocation at given position
@ -133,14 +142,14 @@ public:
* @param tok token where memory is leaked * @param tok token where memory is leaked
* @param varname name of variable * @param varname name of variable
*/ */
void memleakError(const Token *tok, const std::string &varname); void memleakError(const Token *tok, const std::string &varname, bool inconclusive);
/** /**
* Report that there is a resource leak (fopen/popen/etc) * Report that there is a resource leak (fopen/popen/etc)
* @param tok token where resource is leaked * @param tok token where resource is leaked
* @param varname name of variable * @param varname name of variable
*/ */
void resourceLeakError(const Token *tok, const std::string &varname); void resourceLeakError(const Token *tok, const std::string &varname, bool inconclusive);
/** /**
* @brief Report error: deallocating a deallocated pointer * @brief Report error: deallocating a deallocated pointer
@ -312,8 +321,8 @@ public:
void getErrorMessages(ErrorLogger *e, const Settings *settings) { void getErrorMessages(ErrorLogger *e, const Settings *settings) {
CheckMemoryLeakInFunction c(0, settings, e); CheckMemoryLeakInFunction c(0, settings, e);
c.memleakError(0, "varname"); c.memleakError(0, "varname", false);
c.resourceLeakError(0, "varname"); c.resourceLeakError(0, "varname", false);
c.deallocDeallocError(0, "varname"); c.deallocDeallocError(0, "varname");
c.deallocuseError(0, "varname"); c.deallocuseError(0, "varname");

View File

@ -127,7 +127,7 @@ private:
Settings settings; Settings settings;
settings.experimental = experimental; settings.experimental = experimental;
settings.experimental = true; settings.inconclusive = true;
// Tokenize.. // Tokenize..
Tokenizer tokenizer(&settings, this); Tokenizer tokenizer(&settings, this);
@ -909,27 +909,27 @@ private:
"{\n" "{\n"
" int *p = new(std::nothrow) int;\n" " int *p = new(std::nothrow) int;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
" using std::nothrow;\n" " using std::nothrow;\n"
" int *p = new(nothrow) int;\n" " int *p = new(nothrow) int;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
" int *p = new(std::nothrow) int[10];\n" " int *p = new(std::nothrow) int[10];\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
" using namespace std;\n" " using namespace std;\n"
" int *p = new(nothrow) int[10];\n" " int *p = new(nothrow) int[10];\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
@ -1004,7 +1004,7 @@ private:
" str = new char[20];\n" " str = new char[20];\n"
" delete [] str;\n" " delete [] str;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: str (this might be a false warning)\n", errout.str());
} }
@ -1026,7 +1026,7 @@ private:
" }\n" " }\n"
" return NULL;\n" " return NULL;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: s\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: s (this might be a false warning)\n", errout.str());
} }
@ -1119,7 +1119,7 @@ private:
" }\n" " }\n"
" free(c);\n" " free(c);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: c\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: c (this might be a false warning)\n", errout.str());
} }
void if9() { void if9() {
@ -1160,7 +1160,7 @@ private:
" }\n" " }\n"
" delete [] x;\n" " delete [] x;\n"
"}\n", true); "}\n", true);
TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: x\n", TODO_ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: x (this might be a false warning)\n",
"", errout.str()); "", errout.str());
} }
@ -1188,7 +1188,7 @@ private:
" str = strdup(a[i]);\n" " str = strdup(a[i]);\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: str (this might be a false warning)\n", errout.str());
} }
@ -1210,7 +1210,7 @@ private:
"\n" "\n"
" return a;\n" " return a;\n"
"}\n"); "}\n");
TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a\n", TODO_ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a (this might be a false warning)\n",
"[test.cpp:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n", "[test.cpp:8]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n",
errout.str()); errout.str());
@ -1254,7 +1254,7 @@ private:
" return a;\n" " return a;\n"
"}\n", true); "}\n", true);
ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n" ASSERT_EQUALS("[test.cpp:9]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n"
"[test.cpp:11]: (error) Memory leak: a\n", errout.str()); "[test.cpp:11]: (error) Memory leak: a (this might be a false warning)\n", errout.str());
} }
@ -1286,7 +1286,7 @@ private:
" };\n" " };\n"
"}\n"); "}\n");
check(code.c_str(), false); check(code.c_str(), false);
ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: str (this might be a false warning)\n", errout.str());
} }
void switch3() { void switch3() {
@ -1303,7 +1303,7 @@ private:
" }\n" " }\n"
" delete [] str;\n" " delete [] str;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: str (this might be a false warning)\n", errout.str());
} }
void switch4() { void switch4() {
@ -1456,7 +1456,7 @@ private:
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo(p);\n" " foo(p);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
@ -1502,7 +1502,7 @@ private:
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo(p);\n" " foo(p);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
@ -1519,7 +1519,7 @@ private:
" char *p = new char[100];\n" " char *p = new char[100];\n"
" foo(p);\n" " foo(p);\n"
"}\n"); "}\n");
TODO_ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", TODO_ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p (this might be a false warning)\n",
"", errout.str()); "", errout.str());
} }
@ -1612,7 +1612,7 @@ private:
" if (a()) return;\n" // <- memory leak " if (a()) return;\n" // <- memory leak
" free(p);\n" " free(p);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void func16() { void func16() {
@ -1752,7 +1752,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1766,7 +1766,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1797,7 +1797,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1811,7 +1811,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1843,7 +1843,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1857,7 +1857,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo ()\n" check("void foo ()\n"
"{\n" "{\n"
@ -1890,7 +1890,7 @@ private:
" delete [] cpDir;\n" " delete [] cpDir;\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1903,7 +1903,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1934,7 +1934,7 @@ private:
" delete [] cpDir;\n" " delete [] cpDir;\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1947,7 +1947,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1979,7 +1979,7 @@ private:
" delete [] cpDir;\n" " delete [] cpDir;\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -1992,7 +1992,7 @@ private:
" }\n" " }\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: cpDir (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -2027,7 +2027,7 @@ private:
" sprintf(cBuf,\"%s\",\"testtest..\");\n" " sprintf(cBuf,\"%s\",\"testtest..\");\n"
" perror (cBuf);\n" " perror (cBuf);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: cBuf\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: cBuf (this might be a false warning)\n", errout.str());
} }
// # 2668 // # 2668
@ -2044,7 +2044,7 @@ private:
" delete [] cpFile;\n" " delete [] cpFile;\n"
" fclose (stdout);\n" " fclose (stdout);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -2058,7 +2058,7 @@ private:
" }\n" " }\n"
" fclose (stdout);\n" " fclose (stdout);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -2093,7 +2093,7 @@ private:
" delete [] cpFile;\n" " delete [] cpFile;\n"
" return file;\n" " return file;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("int * foo()\n" check("int * foo()\n"
"{\n" "{\n"
@ -2107,7 +2107,7 @@ private:
" }\n" " }\n"
" return file;\n" " return file;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("int * foo()\n" check("int * foo()\n"
"{\n" "{\n"
@ -2139,7 +2139,7 @@ private:
" delete [] cpFile;\n" " delete [] cpFile;\n"
" return file;\n" " return file;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("int * foo()\n" check("int * foo()\n"
"{\n" "{\n"
@ -2153,7 +2153,7 @@ private:
" }\n" " }\n"
" return file;\n" " return file;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: cpFile (this might be a false warning)\n", errout.str());
check("int * foo()\n" check("int * foo()\n"
"{\n" "{\n"
@ -2177,7 +2177,7 @@ private:
"{\n" "{\n"
" std::string *x = new std::string;\n" " std::string *x = new std::string;\n"
"}\n"); "}\n");
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x\n","", errout.str()); TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Memory leak: x (this might be a false warning)\n","", errout.str());
check("void f(void) \n" check("void f(void) \n"
"{\n" "{\n"
@ -2201,7 +2201,7 @@ private:
"{\n" "{\n"
" Fred *f = new Fred();\n" " Fred *f = new Fred();\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: f (this might be a false warning)\n", errout.str());
check("class Fred { void foo(){ } };\n" check("class Fred { void foo(){ } };\n"
"void f(void) \n" "void f(void) \n"
@ -2216,7 +2216,7 @@ private:
"{\n" "{\n"
" Fred *f = new Fred();\n" " Fred *f = new Fred();\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: f (this might be a false warning)\n", errout.str());
} }
@ -2229,7 +2229,7 @@ private:
"{\n" "{\n"
" char *p = a();\n" " char *p = a();\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
check("FILE *a()\n" check("FILE *a()\n"
"{\n" "{\n"
@ -2239,7 +2239,7 @@ private:
"{\n" "{\n"
" FILE *p = a();\n" " FILE *p = a();\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Resource leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Resource leak: p (this might be a false warning)\n"), errout.str());
check("char *a()\n" check("char *a()\n"
"{\n" "{\n"
@ -2249,7 +2249,7 @@ private:
"{\n" "{\n"
" char *p = a();\n" " char *p = a();\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
} }
void allocfunc2() { void allocfunc2() {
@ -2302,7 +2302,7 @@ private:
"{\n" "{\n"
" char *p = a();\n" " char *p = a();\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
} }
void allocfunc4() { void allocfunc4() {
@ -2317,7 +2317,7 @@ private:
"{\n" "{\n"
" char *p = foo();\n" " char *p = foo();\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
check("char* foo()\n" check("char* foo()\n"
"{\n" "{\n"
@ -2345,7 +2345,7 @@ private:
" char *p;\n" " char *p;\n"
" foo(&p);\n" " foo(&p);\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:10]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:10]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
check("void foo(char **str)\n" check("void foo(char **str)\n"
"{\n" "{\n"
@ -2371,7 +2371,7 @@ private:
" char *q;\n" " char *q;\n"
" foo(&q, &p);\n" " foo(&q, &p);\n"
"}\n"); "}\n");
ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p (this might be a false warning)\n"), errout.str());
check("void foo(char **str)\n" check("void foo(char **str)\n"
"{\n" "{\n"
@ -2384,7 +2384,7 @@ private:
" char *p;\n" " char *p;\n"
" foo(&p);\n" " foo(&p);\n"
"}\n"); "}\n");
TODO_ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p\n"), TODO_ASSERT_EQUALS(std::string("[test.cpp:11]: (error) Memory leak: p (this might be a false warning)\n"),
"", errout.str()); "", errout.str());
check("void foo(char **str)\n" check("void foo(char **str)\n"
@ -2469,7 +2469,7 @@ private:
" f = foo();\n" " f = foo();\n"
" fclose(f);\n" " fclose(f);\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:7]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
} }
void allocfunc9() { void allocfunc9() {
@ -2508,7 +2508,7 @@ private:
" delete [] str;\n" " delete [] str;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: str\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: str (this might be a false warning)\n", errout.str());
} }
void throw2() { void throw2() {
@ -2570,7 +2570,7 @@ private:
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: s2\n", errout.str()); ASSERT_EQUALS("[test.cpp:12]: (error) Memory leak: s2 (this might be a false warning)\n", errout.str());
} }
@ -2581,7 +2581,7 @@ private:
" a = realloc(a, 100);\n" " a = realloc(a, 100);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n" ASSERT_EQUALS("[test.cpp:4]: (error) Common realloc mistake: \'a\' nulled but not freed upon failure\n"
"[test.cpp:5]: (error) Memory leak: a\n", errout.str()); "[test.cpp:5]: (error) Memory leak: a (this might be a false warning)\n", errout.str());
} }
void realloc2() { void realloc2() {
@ -2748,7 +2748,7 @@ private:
" free(a);\n" " free(a);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -2825,7 +2825,7 @@ private:
" char *a = reinterpret_cast<char *>(malloc(10));\n" " char *a = reinterpret_cast<char *>(malloc(10));\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: a (this might be a false warning)\n", errout.str());
} }
@ -3022,7 +3022,7 @@ private:
" ThrowException();\n" " ThrowException();\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
check("void foo()\n" check("void foo()\n"
"{\n" "{\n"
@ -3030,7 +3030,7 @@ private:
" p = g();\n" " p = g();\n"
" delete [] p;\n" " delete [] p;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void unknownFunction4() { void unknownFunction4() {
@ -3041,7 +3041,7 @@ private:
" if (b) return;\n" " if (b) return;\n"
" delete [] p;\n" " delete [] p;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void unknownFunction5() { void unknownFunction5() {
@ -3091,7 +3091,7 @@ private:
" int *p = new int[100];\n" " int *p = new int[100];\n"
" }\n" " }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void class2() { void class2() {
@ -3191,7 +3191,7 @@ private:
" exit(0);\n" " exit(0);\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void exit5() { void exit5() {
@ -3237,7 +3237,7 @@ private:
" char *p = malloc(100);\n" " char *p = malloc(100);\n"
" int i = a(123);\n" " int i = a(123);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void noreturn() { void noreturn() {
@ -3259,7 +3259,7 @@ private:
" char *p = malloc(100);\n" " char *p = malloc(100);\n"
" fatal_error();\n" " fatal_error();\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
@ -3271,7 +3271,7 @@ private:
" memset(&(out[0]), 0, 1);\n" " memset(&(out[0]), 0, 1);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: out\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: out (this might be a false warning)\n", errout.str());
} }
void strndup_function() { void strndup_function() {
@ -3279,7 +3279,7 @@ private:
"{\n" "{\n"
" char *out = strndup(\"text\", 3);\n" " char *out = strndup(\"text\", 3);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: out\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: out (this might be a false warning)\n", errout.str());
} }
void tmpfile_function() { void tmpfile_function() {
@ -3287,7 +3287,7 @@ private:
"{\n" "{\n"
" FILE *f = tmpfile();\n" " FILE *f = tmpfile();\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
@ -3295,7 +3295,7 @@ private:
" if (!f)\n" " if (!f)\n"
" return;\n" " return;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
check("void f()\n" check("void f()\n"
"{\n" "{\n"
@ -3341,7 +3341,7 @@ private:
"{\n" "{\n"
" int fd = open(path, O_RDONLY);\n" " int fd = open(path, O_RDONLY);\n"
"}\n", true); "}\n", true);
ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: fd\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: fd (this might be a false warning)\n", errout.str());
check("void f(const char *path)\n" check("void f(const char *path)\n"
"{\n" "{\n"
@ -3387,7 +3387,7 @@ private:
"{\n" "{\n"
" int fd = creat(path, S_IRWXU);\n" " int fd = creat(path, S_IRWXU);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: fd\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: fd (this might be a false warning)\n", errout.str());
} }
void close_function() { void close_function() {
@ -3447,7 +3447,7 @@ private:
" }\n" " }\n"
" close(handle);\n" " close(handle);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:11]: (error) Resource leak: handle\n", errout.str()); ASSERT_EQUALS("[test.cpp:11]: (error) Resource leak: handle (this might be a false warning)\n", errout.str());
} }
void fd_functions() { void fd_functions() {
@ -3475,7 +3475,7 @@ private:
" fstat(fd, buf);\n" " fstat(fd, buf);\n"
" fchmod(fd, mode);\n" " fchmod(fd, mode);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:24]: (error) Resource leak: fd\n", errout.str()); ASSERT_EQUALS("[test.cpp:24]: (error) Resource leak: fd (this might be a false warning)\n", errout.str());
} }
void opendir_function() { void opendir_function() {
@ -3483,7 +3483,7 @@ private:
"{\n" "{\n"
" DIR *f = opendir(\".\");\n" " DIR *f = opendir(\".\");\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
} }
void fdopendir_function() { void fdopendir_function() {
@ -3491,7 +3491,7 @@ private:
"{\n" "{\n"
" DIR *f = fdopendir(fd);\n" " DIR *f = fdopendir(fd);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
} }
void closedir_function() { void closedir_function() {
@ -3528,7 +3528,7 @@ private:
" seekdir(f, 2)\n;" " seekdir(f, 2)\n;"
" scandir(f, namelist, filter, comp);\n;" " scandir(f, namelist, filter, comp);\n;"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:10]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
} }
void file_functions() { void file_functions() {
@ -3554,7 +3554,7 @@ private:
"fgetpos(in, 10);\n" "fgetpos(in, 10);\n"
"fprintf(in, \"text\\n\");\n" "fprintf(in, \"text\\n\");\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:22]: (error) Resource leak: f\n", errout.str()); ASSERT_EQUALS("[test.cpp:22]: (error) Resource leak: f (this might be a false warning)\n", errout.str());
} }
void getc_function() { void getc_function() {
@ -3566,7 +3566,7 @@ private:
" while ( (c = getc (fin1a)) != EOF)\n" " while ( (c = getc (fin1a)) != EOF)\n"
" { }\n" " { }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: fin1a\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: fin1a (this might be a false warning)\n", errout.str());
} }
{ {
@ -3576,7 +3576,7 @@ private:
" FILE *fin1b = fopen(\"FILE.txt\", \"r\");\n" " FILE *fin1b = fopen(\"FILE.txt\", \"r\");\n"
" c = getc(fin1b);\n" " c = getc(fin1b);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: fin1b\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: fin1b (this might be a false warning)\n", errout.str());
} }
} }
@ -3632,7 +3632,7 @@ private:
" int *p = new int[100];\n" " int *p = new int[100];\n"
" typeid(p);\n" " typeid(p);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
void same_function_name() { void same_function_name() {
@ -3651,7 +3651,7 @@ private:
"{\n" "{\n"
" p = malloc(100);\n" " p = malloc(100);\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p (this might be a false warning)\n", errout.str());
} }
// Ticket #2014 - setjmp / longjmp // Ticket #2014 - setjmp / longjmp
@ -3690,7 +3690,7 @@ private:
"return 0;\n" "return 0;\n"
"}\n" "}\n"
); );
ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: buff\n", errout.str()); ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: buff (this might be a false warning)\n", errout.str());
} }
void trac2662() { void trac2662() {
@ -3736,7 +3736,7 @@ private:
"try {}\n" "try {}\n"
"catch(...) {}\n" "catch(...) {}\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: a (this might be a false warning)\n", errout.str());
} }