diff --git a/cfg/windows.cfg b/cfg/windows.cfg index 0dfa5268a..31f1889c6 100644 --- a/cfg/windows.cfg +++ b/cfg/windows.cfg @@ -978,6 +978,10 @@ LockServiceDatabase UnlockServiceDatabase + + HeapCreate + HeapDestroy + ExAllocatePool ExAllocatePoolWithQuota diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 41c89871f..97e4cb0d4 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -1151,3 +1151,87 @@ private: }; REGISTER_TEST(TestLeakAutoVar) + + + + + +class TestLeakAutoVarWindows : public TestFixture { +public: + TestLeakAutoVarWindows() : TestFixture("TestLeakAutoVarWindows") { + } + +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 leaks.. + CheckLeakAutoVar checkLeak; + checkLeak.runSimplifiedChecks(&tokenizer, &settings, this); + } + + void run() { + LOAD_LIB_2(settings.library, "windows.cfg"); + + TEST_CASE(heapDoubleFree); + } + + void heapDoubleFree() { + check("void f() {" + " HANDLE MyHeap = HeapCreate(0, 0, 0);" + " int *a = HeapAlloc(MyHeap, 0, sizeof(int));" + " int *b = HeapAlloc(MyHeap, 0, sizeof(int));" + " HeapFree(MyHeap, 0, a);" + " HeapFree(MyHeap, 0, b);" + " HeapDestroy(MyHeap);" + "}"); + TODO_ASSERT_EQUALS("", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n" + "[test.c:1]: (error) Resource handle 'MyHeap' freed twice.\n", errout.str()); + + check("void f() {" + " int *a = HeapAlloc(GetProcessHeap(), 0, sizeof(int));" + " int *b = HeapAlloc(GetProcessHeap(), 0, sizeof(int));" + " HeapFree(GetProcessHeap(), 0, a);" + " HeapFree(GetProcessHeap(), 0, b);" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f() {" + " HANDLE MyHeap = HeapCreate(0, 0, 0);" + " int *a = HeapAlloc(MyHeap, 0, sizeof(int));" + " int *b = HeapAlloc(MyHeap, 0, sizeof(int));" + " HeapFree(MyHeap, 0, a);" + " HeapDestroy(MyHeap);" + "}"); + TODO_ASSERT_EQUALS("[test.c:1] (error) Memory leak: b", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n" + "[test.c:1]: (error) Memory leak: b\n", errout.str()); + + check("void f() {" + " HANDLE MyHeap = HeapCreate(0, 0, 0);" + " int *a = HeapAlloc(MyHeap, 0, sizeof(int));" + " int *b = HeapAlloc(MyHeap, 0, sizeof(int));" + " HeapFree(MyHeap, 0, a);" + " HeapFree(MyHeap, 0, b);" + "}"); + TODO_ASSERT_EQUALS("[test.c:1] (error) Resource leak: MyHeap", "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n", errout.str()); + + check("void f() {" + " HANDLE MyHeap = HeapCreate(0, 0, 0);" + " int *a = HeapAlloc(MyHeap, 0, sizeof(int));" + " int *b = HeapAlloc(MyHeap, 0, sizeof(int));" + " HeapFree(MyHeap, 0, a);" + "}"); + TODO_ASSERT_EQUALS("[test.c:1] (error) Resource leak: MyHeap\n[test.c:1] (error) Memory leak: b", + "[test.c:1]: (error) Mismatching allocation and deallocation: MyHeap\n[test.c:1]: (error) Memory leak: b\n", errout.str()); + } +}; +static TestLeakAutoVarWindows testLeakAutoVarWindows;