From 1e2545439eae9566a1769df24dd4b3b3e8d062d3 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sun, 24 May 2009 00:26:34 +0700 Subject: [PATCH 1/5] src/checkmemoryleak.cpp(GetDeallocationType): removed brackets. No functional change. --- src/checkmemoryleak.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index fe65b980b..746ce98f0 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -181,9 +181,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const if (Token::simpleMatch(tok, std::string("free ( " + names + " ) ;").c_str()) || Token::simpleMatch(tok, std::string("kfree ( " + names + " ) ;").c_str())) - { return Malloc; - } if (Token::simpleMatch(tok, std::string("g_free ( " + names + " ) ;").c_str())) return gMalloc; From bc62472a18836cb45d23c3ef523c66fcf5ba0bc3 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Wed, 20 May 2009 01:23:43 +0700 Subject: [PATCH 2/5] Part of fix for ticket #284 (style check: redundant condition improvement) Fixed case "if (p != NULL) delete p;" and also added test case for it. http://apps.sourceforge.net/trac/cppcheck/ticket/284 --- src/checkother.cpp | 2 +- test/testother.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/checkother.cpp b/src/checkother.cpp index fc5bde097..8ef7c59a7 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -82,7 +82,7 @@ void CheckOther::WarningRedundantCode() varname1 = tok->strAt(2); tok2 = tok->tokAt(4); } - else if (Token::Match(tok, "if ( %var% != NULL )")) + else if (Token::Match(tok, "if ( %var% != 0 )")) { varname1 = tok->strAt(2); tok2 = tok->tokAt(6); diff --git a/test/testother.cpp b/test/testother.cpp index 6b5381d76..89986865b 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -145,6 +145,13 @@ private: " delete p;\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str()); + + check("void foo()\n" + "{\n" + " if (p != NULL)\n" + " delete p;\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str()); } void unreachable1() From f5300ae56c960a046c3ef726500617ebeec9b079 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Wed, 20 May 2009 01:28:25 +0700 Subject: [PATCH 3/5] Part of fix for ticket #284 (style check: redundant condition improvement) Fixed case "if (p) delete [] p;" and also added test case for it. http://apps.sourceforge.net/trac/cppcheck/ticket/284 --- src/checkother.cpp | 4 ++-- test/testother.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/checkother.cpp b/src/checkother.cpp index 8ef7c59a7..2fc7ee54e 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -102,7 +102,7 @@ void CheckOther::WarningRedundantCode() } else if (Token::Match(tok2, "delete [ ] %var% ; }")) { - err = (strcmp(tok2->strAt(1), varname1) == 0); + err = (strcmp(tok2->strAt(3), varname1) == 0); } else if (Token::Match(tok2, "free ( %var% ) ; }")) { @@ -121,7 +121,7 @@ void CheckOther::WarningRedundantCode() } else if (Token::Match(tok2, "delete [ ] %var% ;")) { - err = (strcmp(tok2->strAt(1), varname1) == 0); + err = (strcmp(tok2->strAt(3), varname1) == 0); } else if (Token::Match(tok2, "free ( %var% ) ;")) { diff --git a/test/testother.cpp b/test/testother.cpp index 89986865b..5cc7adce4 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -152,6 +152,13 @@ private: " delete p;\n" "}\n"); ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str()); + + check("void foo()\n" + "{\n" + " if (p)\n" + " delete [] p;\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str()); } void unreachable1() From 2654a4aa54457f71b5dbcdc43ee714a054e65069 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Fri, 22 May 2009 14:24:03 +0700 Subject: [PATCH 4/5] Added support to search resource leaks after opendir()/fdopendir() usage. --- src/checkmemoryleak.cpp | 16 +++++++++-- src/checkmemoryleak.h | 2 +- test/testmemleak.cpp | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index 746ce98f0..19cbeede1 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -116,6 +116,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType(const To if (Token::simpleMatch(tok2, "popen (")) return Pipe; + if (Token::simpleMatch(tok2, "opendir (") || Token::simpleMatch(tok2, "fdopendir (")) + return Dir; + // Userdefined allocation function.. std::list::const_iterator it = _listAllocFunc.begin(); while (it != _listAllocFunc.end()) @@ -193,6 +196,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const if (Token::simpleMatch(tok, std::string("pclose ( " + names + " )").c_str())) return Pipe; + if (Token::simpleMatch(tok, std::string("closedir ( " + names + " )").c_str())) + return Dir; + return No; } //-------------------------------------------------------------------------- @@ -217,6 +223,11 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list if (parlevel <= 0) break; } - if (Token::simpleMatch(tok2, std::string("fclose ( " + varnameStr + " )").c_str())) + if (Token::Match(tok2, std::string("fclose|closedir ( " + varnameStr + " )").c_str())) { addtoken("dealloc"); addtoken(";"); diff --git a/src/checkmemoryleak.h b/src/checkmemoryleak.h index 1d5c72e9a..9ce1729e6 100644 --- a/src/checkmemoryleak.h +++ b/src/checkmemoryleak.h @@ -56,7 +56,7 @@ public: private: /** 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, Pipe, Many }; + enum AllocType { No, Malloc, gMalloc, New, NewArray, File, Pipe, Dir, Many }; // Extra allocation.. class AllocFunc diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index b5fddb0b0..206c973ad 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -217,6 +217,12 @@ private: TEST_CASE(strndup_function); TEST_CASE(fcloseall_function); TEST_CASE(file_functions); + + TEST_CASE(opendir_function); + TEST_CASE(fdopendir_function); + TEST_CASE(closedir_function); + TEST_CASE(dir_functions); + TEST_CASE(pointer_to_pointer); } @@ -2190,6 +2196,63 @@ private: ASSERT_EQUALS(std::string(""), errout.str()); } + void opendir_function() + { + check("void f()\n" + "{\n" + " DIR *f = opendir(\".\");\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Resource leak: f\n"), errout.str()); + } + + void fdopendir_function() + { + check("void f(int fd)\n" + "{\n" + " DIR *f = fdopendir(fd);\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Resource leak: f\n"), errout.str()); + } + + void closedir_function() + { + check("void f()\n" + "{\n" + " DIR *f = opendir(\".\");\n" + " closedir(f);\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + + check("void f(int fd)\n" + "{\n" + " DIR *f = fdopendir(fd);\n" + " closedir(f);\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + + check("void foo()\n" + "{\n" + " DIR * f = opendir(dirname);\n" + " if (closedir(f));\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + } + + void dir_functions() + { + check("void f()\n" + "{\n" + " DIR *f = opendir(dir);\n" + " readdir(f);\n;" + " readdir_r(f, entry, res);\n;" + " rewinddir(f);\n;" + " telldir(f);\n;" + " seekdir(f, 2)\n;" + " scandir(f, namelist, filter, comp);\n;" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:10]: (error) Resource leak: f\n"), errout.str()); + } + void file_functions() { check("void f()\n" From 9ae9ffa9bef21197fd6e43e47ffcce593a6f8b67 Mon Sep 17 00:00:00 2001 From: Slava Semushin Date: Sun, 24 May 2009 03:45:14 +0700 Subject: [PATCH 5/5] src/checkmemoryleak.cpp(GetAllocationType): simplify condition a bit. Replace two Token::simpleMatch() calls to one Token::Match(). Correction for my previous (2654a4aa54457f71b5dbcdc43ee714a054e65069) commit. No functional change. --- src/checkmemoryleak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index 19cbeede1..6011f47e8 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -116,7 +116,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType(const To if (Token::simpleMatch(tok2, "popen (")) return Pipe; - if (Token::simpleMatch(tok2, "opendir (") || Token::simpleMatch(tok2, "fdopendir (")) + if (Token::Match(tok2, "opendir|fdopendir (")) return Dir; // Userdefined allocation function..