parent
9765a2dfab
commit
21f7274533
|
@ -2091,207 +2091,3 @@ private:
|
|||
REGISTER_TEST(TestMemleakNoVar)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestMemleakGLib : public TestFixture {
|
||||
public:
|
||||
TestMemleakGLib() : TestFixture("TestMemleakGLib") {
|
||||
}
|
||||
|
||||
private:
|
||||
Settings settings;
|
||||
|
||||
void check(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
std::istringstream istr(code);
|
||||
std::vector<std::string> files(1, "test.cpp");
|
||||
const simplecpp::TokenList tokens1(istr, files, files[0]);
|
||||
|
||||
// Preprocess...
|
||||
Preprocessor preprocessor(settings, this);
|
||||
const simplecpp::TokenList &tokens2 = preprocessor.preprocess(tokens1, "", files);
|
||||
|
||||
// Tokenizer..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
tokenizer.createTokens(&tokens2);
|
||||
tokenizer.simplifyTokenList1(files[0].c_str());
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
// Check for memory leaks..
|
||||
CheckMemoryLeakInFunction checkMemoryLeak1(&tokenizer, &settings, this);
|
||||
CheckMemoryLeakInClass checkMemoryLeak2(&tokenizer, &settings, this);
|
||||
CheckMemoryLeakStructMember checkMemoryLeak3(&tokenizer, &settings, this);
|
||||
CheckMemoryLeakNoVar checkMemoryLeak4(&tokenizer, &settings, this);
|
||||
checkMemoryLeak1.checkReallocUsage();
|
||||
checkMemoryLeak2.check();
|
||||
checkMemoryLeak3.check();
|
||||
checkMemoryLeak4.check();
|
||||
}
|
||||
|
||||
void run() OVERRIDE {
|
||||
LOAD_LIB_2(settings.library, "gtk.cfg");
|
||||
settings.addEnabled("all");
|
||||
return;
|
||||
TEST_CASE(glib1);
|
||||
TEST_CASE(glib2); // #2806 - FP when using redundant assignment
|
||||
}
|
||||
|
||||
void glib1() {
|
||||
check("void f(gchar *_a, gchar *_b) {"
|
||||
" g_return_if_fail(_a);"
|
||||
" gchar *a = g_strdup(_a);"
|
||||
" g_return_if_fail(_b);"
|
||||
" gchar *b = g_strdup(_b);"
|
||||
" g_free(a);"
|
||||
" g_free(b);"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (error) Memory leak: a\n", errout.str());
|
||||
|
||||
check("void x() {\n"
|
||||
" g_strlcpy(a, g_strdup(p));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with g_strdup, g_strlcpy doesn't release it.\n", errout.str());
|
||||
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" if(TRUE || g_strcmp0(g_strdup(a), b));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (error) Allocation with g_strdup, g_strcmp0 doesn't release it.\n", errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" int *p = g_malloc(3);\n"
|
||||
" g_free(p);\n"
|
||||
"}\n");
|
||||
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) The allocated size 3 is not a multiple of the underlying type's size.\n", "", errout.str());
|
||||
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
"private:\n"
|
||||
" char *str1;\n"
|
||||
"public:\n"
|
||||
" Fred()\n"
|
||||
" {\n"
|
||||
" str1 = new char[10];\n"
|
||||
" }\n"
|
||||
" ~Fred()\n"
|
||||
" {\n"
|
||||
" g_free(str1);\n"
|
||||
" }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:12]: (error) Mismatching allocation and deallocation: Fred::str1\n", errout.str());
|
||||
|
||||
check("class Fred\n"
|
||||
"{\n"
|
||||
"private:\n"
|
||||
" gchar *s;\n"
|
||||
"public:\n"
|
||||
" Fred() { s = 0; }\n"
|
||||
" ~Fred() { g_free(s); }\n"
|
||||
" void xy()\n"
|
||||
" { s = g_malloc(100); }\n"
|
||||
"};");
|
||||
ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 's' is not deallocated before it is allocated.\n", errout.str());
|
||||
}
|
||||
|
||||
void glib2() {
|
||||
// #2806 - FP when there is redundant assignment
|
||||
check("void foo() {\n"
|
||||
" gchar *bar;\n"
|
||||
" bar = g_strdup(fuba);\n"
|
||||
" bar = g_strstrip(bar);\n"
|
||||
" g_free(bar);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void* foo()\n"
|
||||
"{\n"
|
||||
" char *p1 = g_malloc(10);\n"
|
||||
" char *p2 = g_strlcpy(p1, \"a\");\n"
|
||||
" return p2;\n"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("", "[test.cpp:5]: (error) Memory leak: p1\n", errout.str());
|
||||
}
|
||||
};
|
||||
REGISTER_TEST(TestMemleakGLib)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TestMemleakWindows : public TestFixture {
|
||||
public:
|
||||
TestMemleakWindows() : TestFixture("TestMemleakWindows") {
|
||||
}
|
||||
|
||||
private:
|
||||
Settings settings;
|
||||
|
||||
void check(const char code[]) {
|
||||
// Clear the error buffer..
|
||||
errout.str("");
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.c");
|
||||
tokenizer.simplifyTokenList2();
|
||||
|
||||
// Check for memory leaks..
|
||||
CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this);
|
||||
checkMemoryLeak.checkReallocUsage();
|
||||
}
|
||||
|
||||
void run() OVERRIDE {
|
||||
LOAD_LIB_2(settings.library, "windows.cfg");
|
||||
return;
|
||||
TEST_CASE(openfileNoLeak);
|
||||
TEST_CASE(returnValueNotUsed_tfopen_s);
|
||||
TEST_CASE(sendMessage);
|
||||
}
|
||||
|
||||
void openfileNoLeak() {
|
||||
check("void f() {"
|
||||
" OFSTRUCT OfStr;"
|
||||
" int hFile = OpenFile(\"file\", &OfStr, 0);"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.c:1]: (error) Resource leak: hFile\n", errout.str());
|
||||
|
||||
check("void f() {"
|
||||
" OFSTRUCT OfStr;"
|
||||
" int hFile = OpenFile(\"file\", &OfStr, OF_EXIST);"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("", "[test.c:1]: (error) Resource leak: hFile\n", errout.str());
|
||||
}
|
||||
|
||||
void returnValueNotUsed_tfopen_s() {
|
||||
check("bool LoadFile(LPCTSTR filename) {\n"
|
||||
" FILE *fp = NULL;\n"
|
||||
" _tfopen_s(&fp, filename, _T(\"rb\"));\n"
|
||||
" if (!fp)\n"
|
||||
" return false;\n"
|
||||
" fclose(fp);\n"
|
||||
" return true;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("bool LoadFile(LPCTSTR filename) {\n"
|
||||
" FILE *fp = NULL;\n"
|
||||
" _tfopen_s(&fp, filename, _T(\"rb\"));\n"
|
||||
"}");
|
||||
TODO_ASSERT_EQUALS("[test.c:3]: (error) Resource leak: fp\n", "", errout.str());
|
||||
}
|
||||
|
||||
void sendMessage() {
|
||||
check("void SetFont() {\n"
|
||||
" HFONT hf = CreateFontIndirect(&lf);\n"
|
||||
" SendMessage(hwnd, WM_SETFONT, (WPARAM)hf, TRUE);\n" // We do not know what the handler for the message will do with 'hf', so it might be closed later
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestMemleakWindows)
|
||||
|
|
Loading…
Reference in New Issue