First draft for discussion. Not, um, well tested yet.
ANSI C++ mandates separate vector versions of new and delete
that do the same thing as the non-vector versions, but which can
be replaced by user apps (see
http://www.csci.csusb.edu/dick/c++std/cd2/lib-support.html#lib.new.delete )
So far, so good; wine does that in msvcrt.
However, once in a while, a programmer will call delete when he
should have called delete[], and a bunch of destructors won't
get called. To detect this programming error, let's split
the vector new and delete functions off from their scalar twins,
and add values for the heap function flags so we can inform
valgrind what kind of blocks are being wrangled.
This means picking two flag bits that Microsoft doesn't use;
there seem to be enough to go around.
Requires the corresponding patch to valgrind
ttps://bugs.kde.org/show_bug.cgi?id=218741
Thanks to Steve Vandebogart for his help on this; he wrote a bunch of it.
diff --git a/dlls/msvcrt/heap.c b/dlls/msvcrt/heap.c
index e40a0c9..c1e5620 100644
--- a/dlls/msvcrt/heap.c
+++ b/dlls/msvcrt/heap.c
@@ -65,6 +65,25 @@ void* CDECL MSVCRT_operator_new(MSVCRT_size_t size)
}
/*********************************************************************
+ * ?...@yapaxi@Z (MSVCRT.@)
+ *
+ * Called by e.g. new int[10].
+ * (Also appears in default static library libcpmt, so to see this get called
+ * in programs compiled by visual C++, you have to compile with /nodefaultlib.)
+ */
+void* CDECL MSVCRT_operator_vec_new(MSVCRT_size_t size)
+{
+ void *retval = HeapAlloc(GetProcessHeap(), 0, size);
+ TRACE("(%ld) returning %p\n", size, retval);
+ if(retval) return retval;
+ LOCK_HEAP;
+ if(MSVCRT_new_handler)
+ (*MSVCRT_new_handler)(size);
+ UNLOCK_HEAP;
+ return retval;
+}
+
+/*********************************************************************
* ?...@yaxpax@Z (MSVCRT.@)
*/
void CDECL MSVCRT_operator_delete(void *mem)
@@ -73,6 +92,19 @@ void CDECL MSVCRT_operator_delete(void *mem)
HeapFree(GetProcessHeap(), 0, mem);
}
+/*********************************************************************
+ * ?...@yaxpax@Z (MSVCRT.@)
+ *
+ * Called by e.g. int *p = new int[10]; delete[] p;
+ * (Also appears in default static library libcpmt, so to see this get called
+ * in programs compiled by visual C++, you have to compile with /nodefaultlib.)
+ */
+void CDECL MSVCRT_operator_vec_delete(void *mem)
+{
+ TRACE("(%p)\n", mem);
+ HeapFree(GetProcessHeap(), 0, mem);
+}
+
/*********************************************************************
* ?_query_new_handler@@yap6...@zxz (MSVCRT.@)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index c6c749d..12f9402 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -16,9 +16,9 @@
@ cdecl -i386 -norelay ??1exception@@u...@xz() __thiscall_MSVCRT_exception_dtor
@ cdecl -i386 -norelay ??1type_info@@u...@xz() __thiscall_MSVCRT_type_info_dtor
@ cdecl ?...@yapaxi@Z(long) MSVCRT_operator_new
-@ cdecl ?...@yapaxi@Z(long) MSVCRT_operator_new
+@ cdecl ?...@yapaxi@Z(long) MSVCRT_operator_vec_new
@ cdecl ?...@yaxpax@Z(ptr) MSVCRT_operator_delete
-@ cdecl ?...@yaxpax@Z(ptr) MSVCRT_operator_delete
+@ cdecl ?...@yaxpax@Z(ptr) MSVCRT_operator_vec_delete
@ cdecl -i386 -norelay ??4__non_rtti_object@@qaea...@abv0@@Z(ptr) __thiscall_MSVCRT___non_rtti_object_opequals
@ cdecl -i386 -norelay ??4bad_cast@@qaea...@abv0@@Z(ptr) __thiscall_MSVCRT_bad_cast_opequals
@ cdecl -i386 -norelay ??4bad_typeid@@qaea...@abv0@@Z(ptr) __thiscall_MSVCRT_bad_typeid_opequals