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;