From: Paul Floyd Date: Sun, 12 Mar 2023 07:26:04 +0000 (+0100) Subject: Add memcheck errors for aligned and sized allocations and deallocations X-Git-Tag: VALGRIND_3_22_0~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a265a206203003cc0433f786478fe81a6cc3298a;p=thirdparty%2Fvalgrind.git Add memcheck errors for aligned and sized allocations and deallocations Bug 433857 Add validation to C++17 aligned new/delete alignment size Bug 433859 Add mismatched detection to C++ 17 aligned new/delete Bug 466105 aligned_alloc problems, part 2 Bug 467441 Add mismatched detection to C++ 14 sized delete Memcheck now tests and warns about the values used for alignment and size. These apply to various functions: memalign, posix_memalign and aligned_alloc in C and various overloads of operators new and delete in C++. The kinds of error that can be detected are - invalid alignment, for instance the alignment is usually required to be a power of 2 - mismatched alignment between aligned allocation and aligned deallocation - mismatched size when sized delete is used - bad size for functions that have implementation defined behaviour when the requested size is zero An example of the new errors is: int *pi = memalign(31, 100); which will generate the following error ==96206== Invalid alignment value: 31 (should be power of 2) ==96206== at 0x485195E: memalign (vg_replace_malloc.c:1886) ==96206== by 0x20200E: main (memalign.c:59) --- diff --git a/.gitignore b/.gitignore index 6538eb718b..6aeb41df94 100644 --- a/.gitignore +++ b/.gitignore @@ -866,6 +866,7 @@ /memcheck/tests/descr_belowsp /memcheck/tests/dir /memcheck/tests/doublefree +/memcheck/tests/duplicate_align_size_errors /memcheck/tests/dw4 /memcheck/tests/erringfds /memcheck/tests/error_counts @@ -932,6 +933,7 @@ /memcheck/tests/nanoleak /memcheck/tests/nanoleak2 /memcheck/tests/nanoleak_supp +/memcheck/tests/new_delete_mismatch_size /memcheck/tests/new_nothrow /memcheck/tests/new_override /memcheck/tests/noisy_child @@ -971,7 +973,9 @@ /memcheck/tests/sh-mem /memcheck/tests/sh-mem-random /memcheck/tests/sized_aligned_new_delete_args -/memcheck/tests/sized_aligned_new_delete_misaligned +/memcheck/tests/sized_aligned_new_delete_misaligned1 +/memcheck/tests/sized_aligned_new_delete_misaligned2 +/memcheck/tests/sized_aligned_new_delete_misaligned3 /memcheck/tests/sigaltstack /memcheck/tests/sigkill /memcheck/tests/signal2 @@ -1341,11 +1345,13 @@ /memcheck/tests/freebsd/Makefile.in /memcheck/tests/freebsd/452275 /memcheck/tests/freebsd/access +/memcheck/tests/freebsd/aligned_alloc /memcheck/tests/freebsd/bug464476 /memcheck/tests/freebsd/bug470713 /memcheck/tests/freebsd/capsicum /memcheck/tests/freebsd/chflags /memcheck/tests/freebsd/chmod_chown +/memcheck/tests/freebsd/delete_sized_mismatch /memcheck/tests/freebsd/errno_aligned_allocs /memcheck/tests/freebsd/eventfd1 /memcheck/tests/freebsd/eventfd2 diff --git a/NEWS b/NEWS index 41f6d8699a..7c5247f071 100644 --- a/NEWS +++ b/NEWS @@ -22,9 +22,20 @@ AMD64/macOS 10.13 and nanoMIPS/Linux. * support has been added for FreeBSD 14 and FreeBSD 15. - * ==================== TOOL CHANGES =================== +* Memcheck now tests and warns about the values used for + alignment and size. These apply to various functions: memalign, + posix_memalign and aligned_alloc in C and various overloads + of operators new and delete in C++. The kinds of error that can + be detected are + - invalid alignment, for instance the alignment is usually required + to be a power of 2 + - mismatched alignment between aligned allocation and aligned + deallocation + - mismatched size when sized delete is used + - bad size for functions that have implementation defined behaviour + when the requested size is zero * ==================== FIXED BUGS ==================== @@ -35,8 +46,12 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. -426751 Valgrind reports «still reachable» memory using musl (alpine running inside docker) +426751 Valgrind reports "still reachable" memory using musl (alpine running inside docker) +433857 Add validation to C++17 aligned new/delete alignment size +433859 Add mismatched detection to C++ 17 aligned new/delete 460192 Add epoll_pwait2 +466105 aligned_alloc problems, part 2 +467441 Add mismatched detection to C++ 14 sized delete 469049 link failure on ppc64 (big endian) valgrind 3.20 469146 massif --ignore-fn does not ignore inlined functions 469768 Make it possible to install gdb scripts in a different location diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index a71aa4b5b2..6c6f0d60f7 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -67,9 +67,14 @@ #include "pub_core_mallocfree.h" // for VG_MIN_MALLOC_SZB, VG_AR_CLIENT #include "pub_core_redir.h" // for VG_REPLACE_FUNCTION_* #include "pub_core_replacemalloc.h" +#include "../../memcheck/memcheck.h" #define VG_ALIGN_ROUNDUP(size, alignment) (((size) + (alignment) - 1) & ~((alignment) - 1)) +#define VERIFY_ALIGNMENT(aligned_alloc_info) \ + VALGRIND_DO_CLIENT_REQUEST_STMT(_VG_USERREQ__MEMCHECK_VERIFY_ALIGNMENT, \ + aligned_alloc_info, 0, 0, 0, 0) + /* Assignment of behavioural equivalence class tags: 1NNNP is intended to be reserved for the Valgrind core. Current usage: @@ -307,15 +312,18 @@ extern int * __error(void) __attribute__((weak)); /* Generate a replacement for 'fnname' in object 'soname', which calls 'vg_replacement' to allocate aligned memory. If that fails, return NULL. */ -#define ALLOC_or_NULL_ALIGNED(soname, fnname, vg_replacement) \ +#define ALLOC_or_NULL_ALIGNED(soname, fnname, vg_replacement, tag) \ \ void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n, SizeT alignment); \ void* VG_REPLACE_FUNCTION_EZU(10010,soname,fnname) (SizeT n, SizeT alignment) \ { \ void* v; \ + SizeT orig_alignment = alignment; \ \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=n, .alloc_kind=AllocKind##tag}; \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ \ if ((alignment == 0) \ @@ -327,7 +335,7 @@ extern int * __error(void) __attribute__((weak)); if (alignment < VG_MIN_MALLOC_SZB) \ alignment = VG_MIN_MALLOC_SZB; \ \ - v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_##vg_replacement, n, alignment ); \ + v = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_##vg_replacement, n, alignment, orig_alignment ); \ MALLOC_TRACE(" = %p\n", v ); \ if (!v) SET_ERRNO_ENOMEM; \ return v; \ @@ -382,15 +390,18 @@ extern int * __error(void) __attribute__((weak)); 'vg_replacement' to allocate aligned memory. If that fails, it bombs the system. */ -#define ALLOC_or_BOMB_ALIGNED(soname, fnname, vg_replacement) \ +#define ALLOC_or_BOMB_ALIGNED(soname, fnname, vg_replacement, tag) \ \ void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n, SizeT alignment); \ void* VG_REPLACE_FUNCTION_EZU(10030,soname,fnname) (SizeT n, SizeT alignment) \ { \ void* v; \ + SizeT orig_alignment = alignment; \ \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=n, .alloc_kind=AllocKind##tag }; \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \ \ if ((alignment == 0) \ @@ -406,7 +417,7 @@ extern int * __error(void) __attribute__((weak)); if (alignment < VG_MIN_MALLOC_SZB) \ alignment = VG_MIN_MALLOC_SZB; \ \ - v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_##vg_replacement, n, alignment ); \ + v = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_##vg_replacement, n, alignment, orig_alignment ); \ MALLOC_TRACE(" = %p\n", v ); \ if (NULL == v) { \ VALGRIND_PRINTF( \ @@ -519,55 +530,55 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator new(unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); #endif // operator new(unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_freebsd) - // operator new(unsigned int) + // operator new(unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); #endif - // operator new(unsigned long) + // operator new(unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_darwin) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); #endif #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_solaris) // operator new(unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_t, __builtin_new_aligned, NewAligned); #endif // operator new(unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_t, __builtin_new_aligned, NewAligned); #endif @@ -639,55 +650,55 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator new(unsigned int, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif // operator new(unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_freebsd) // operator new(unsigned int, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif // operator new(unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_darwin) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif #elif defined(VGO_solaris) // operator new(unsigned, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, __ZnwjSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif // operator new(unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnwmSt11align_val_tRKSt9nothrow_t, __builtin_new_aligned, NewAligned); #endif #endif @@ -761,57 +772,57 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator new[](unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_freebsd) // operator new[](unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_darwin) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_solaris) // operator new[](unsigned int, std::align_val_t) #if VG_WORDSIZE == 4 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t) #if VG_WORDSIZE == 8 - ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); - ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned ); + ALLOC_or_BOMB_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_BOMB_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #endif @@ -882,57 +893,57 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBC_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_freebsd) // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_darwin) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #elif defined(VGO_solaris) // operator new[](unsigned int, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 4 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnajSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif // operator new[](unsigned long, std::align_val_t, std::nothrow_t const&) #if VG_WORDSIZE == 8 - ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); - ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned ); + ALLOC_or_NULL_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); + ALLOC_or_NULL_ALIGNED(SO_SYN_MALLOC, _ZnamSt11align_val_tRKSt9nothrow_t, __builtin_vec_new_aligned, VecNewAligned ); #endif #endif @@ -1044,13 +1055,16 @@ extern int * __error(void) __attribute__((weak)); /*------------------- C++14 delete sized -------------------*/ -#define DELETE_SIZED(soname, fnname, vg_replacement) \ +#define DELETE_SIZED(soname, fnname, vg_replacement, tag) \ \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT size); \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT size) \ { \ + struct AlignedAllocInfo aligned_alloc_info = { .size=size, .mem=p, .alloc_kind=AllocKind##tag }; \ + \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE(#fnname "(%p)\n", p ); \ if (p == NULL) \ return; \ @@ -1060,79 +1074,89 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete(void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete, DeleteSized ); // operator delete(void*, unsigned long) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete, DeleteSized ); #endif #elif defined(VGO_freebsd) // operator delete(void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete, DeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 // operator delete(void*, unsigned long) - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete, DeleteSized ); #endif #elif defined(VGO_darwin) // operator delete(void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete, DeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 // operator delete(void*, unsigned long) - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete, DeleteSized ); #endif #elif defined(VGO_solaris) // operator delete(void*, unsigned long) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvj, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvj, __builtin_delete, DeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvm, __builtin_delete, DeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdlPvm, __builtin_delete, DeleteSized ); #endif #endif /*------------------- C++17 delete aligned -------------------*/ -#define DELETE_ALIGNED(soname, fnname, vg_replacement) \ +/* No need to check the alignment + * either the alignment matches the alloc + * or the alloc would have failed */ + +#define DELETE_ALIGNED(soname, fnname, vg_replacement, tag ) \ \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT alignment); \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT alignment) \ { \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .mem=p, .alloc_kind=AllocKind##tag }; \ + \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE(#fnname "(%p)\n", p ); \ if (p == NULL) \ return; \ (void)VALGRIND_NON_SIMD_CALL1( info.tl_##vg_replacement, p ); \ } -#define DELETE_SIZED_ALIGNED(soname, fnname, vg_replacement) \ +#define DELETE_SIZED_ALIGNED(soname, fnname, vg_replacement, tag ) \ \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT size, SizeT alignment); \ void VG_REPLACE_FUNCTION_EZU(10050,soname,fnname) (void *p, SizeT size, SizeT alignment) \ { \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=size, .mem=p, .alloc_kind=AllocKind##tag }; \ + \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)size); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)alignment); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE(#fnname "(%p)\n", p ); \ if (p == NULL) \ return; \ @@ -1141,76 +1165,76 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete(void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); // operator delete(void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); // operator delete(void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); #endif #elif defined(VGO_freebsd) // operator delete(void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); // operator delete(void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); // operator delete(void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); #endif #elif defined(VGO_darwin) // operator delete(void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); // operator delete(void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); // operator delete(void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); #endif #elif defined(VGO_solaris) // operator delete(void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_t, __builtin_delete_aligned, DeleteAligned ); // operator delete(void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvjSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); // operator delete(void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdlPvmSt11align_val_t, __builtin_delete_aligned, DeleteSizedAligned ); #endif #endif @@ -1247,29 +1271,29 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete(void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); // no sized version of this operator #elif defined(VGO_freebsd) // operator delete(void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); #elif defined(VGO_darwin) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); #elif defined(VGO_solaris) // operator delete(void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdlPvSt11align_val_tRKSt9nothrow_t, __builtin_delete_aligned, DeleteAligned ); // no sized version of this operator @@ -1311,51 +1335,51 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete[](void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBC_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); #endif #elif defined(VGO_freebsd) // operator delete[](void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); #endif #elif defined(VGO_darwin) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(VG_Z_LIBCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); #endif #elif defined(VGO_solaris) // operator delete[](void*, unsigned int) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvj, __builtin_vec_delete, VecDeleteSized ); // operator delete[](void*, unsigned long) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete ); - DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete ); + DELETE_SIZED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); + DELETE_SIZED(SO_SYN_MALLOC, _ZdaPvm, __builtin_vec_delete, VecDeleteSized ); #endif #endif @@ -1364,76 +1388,76 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete[](void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // operator delete[](void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); // operator delete[](void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); #endif #elif defined(VGO_freebsd) // operator delete[](void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // operator delete[](void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); // operator delete[](void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); #endif #elif defined(VGO_darwin) // operator delete[](void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // operator delete[](void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); // operator delete[](void*, unsigned long, std::align_val_t) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); #endif #elif defined(VGO_solaris) - // operator delete[](void*, std::align_val_t) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned ); + // operator delete[](void*, std::align_val_t), GNU mangling + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // operator delete[](void*, unsigned int, std::align_val_t) #if __SIZEOF_SIZE_T__ == 4 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvjSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); // operator delete[](void*, unsigned long) #elif __SIZEOF_SIZE_T__ == 8 - DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); - DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned ); + DELETE_SIZED_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); + DELETE_SIZED_ALIGNED(SO_SYN_MALLOC, _ZdaPvmSt11align_val_t, __builtin_vec_delete_aligned, VecDeleteSizedAligned ); #endif #endif @@ -1470,29 +1494,29 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_linux) // operator delete[](void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBC_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // no sized version of this operator #elif defined(VGO_freebsd) // operator delete[](void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); #elif defined(VGO_darwin) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(VG_Z_LIBCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); #elif defined(VGO_solaris) // operator delete[](void*, std::align_val_t, std::nothrow_t const&) - DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); - DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned ); + DELETE_ALIGNED(VG_Z_LIBSTDCXX_SONAME, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); + DELETE_ALIGNED(SO_SYN_MALLOC, _ZdaPvSt11align_val_tRKSt9nothrow_t, __builtin_vec_delete_aligned, VecDeleteAligned ); // no sized version of this operator @@ -1700,38 +1724,46 @@ extern int * __error(void) __attribute__((weak)); /* Probably in the wrong place, this is the function called by posix_memalign, at least on macOS 10.13 */ -#define ZONEMEMALIGN(soname, fnname) \ - \ - void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ - ( void *zone, SizeT alignment, SizeT n ); \ - void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \ - ( void *zone, SizeT alignment, SizeT n ) \ - { \ - void* v; \ - \ - DO_INIT; \ - TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \ - TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ - MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", \ - zone, (ULong)alignment, (ULong)n ); \ - \ - if (alignment == 0 \ - || alignment % sizeof (void *) != 0 \ - || (alignment & (alignment - 1)) != 0) { \ - SET_ERRNO_EINVAL; \ - return NULL; \ - } \ - /* Round up to minimum alignment if necessary. */ \ - if (alignment < VG_MIN_MALLOC_SZB) \ - alignment = VG_MIN_MALLOC_SZB; \ - \ - /* Round up to nearest power-of-two if necessary (like glibc). */ \ - while (0 != (alignment & (alignment - 1))) alignment++; \ - \ - v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ - MALLOC_TRACE(" = %p\n", v ); \ - if (!v) SET_ERRNO_ENOMEM; \ - return v; \ +#define ZONEMEMALIGN(soname, fnname) \ + \ + void* VG_REPLACE_FUNCTION_EZU(10100, soname, fnname)( \ + void* zone, SizeT alignment, SizeT n); \ + void* VG_REPLACE_FUNCTION_EZU(10100, soname, \ + fnname)(void* zone, SizeT alignment, SizeT n) \ + { \ + void* v; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { \ + .orig_alignment = alignment, \ + .size = n, \ + .alloc_kind = AllocKindPosixMemalign}; \ + \ + DO_INIT; \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord)zone); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + MALLOC_TRACE("zone_memalign(%p, al %llu, size %llu)", zone, \ + (ULong)alignment, (ULong)n); \ + \ + if (alignment == 0 || alignment % sizeof(void*) != 0 || \ + (alignment & (alignment - 1)) != 0) { \ + SET_ERRNO_EINVAL; \ + return NULL; \ + } \ + /* Round up to minimum alignment if necessary. */ \ + if (alignment < VG_MIN_MALLOC_SZB) \ + alignment = VG_MIN_MALLOC_SZB; \ + \ + /* Round up to nearest power-of-two if necessary (like glibc). */ \ + while (0 != (alignment & (alignment - 1))) \ + alignment++; \ + \ + v = (void*)VALGRIND_NON_SIMD_CALL3(info.tl_memalign, alignment, \ + orig_alignment, n); \ + MALLOC_TRACE(" = %p\n", v); \ + if (!v) \ + SET_ERRNO_ENOMEM; \ + return v; \ } #if defined(VGO_freebsd) @@ -1750,8 +1782,10 @@ extern int * __error(void) __attribute__((weak)); #if defined(VGO_solaris) #define VG_MEMALIGN_ALIGN_FACTOR_FOUR 1 +#define VG_MEMALIGN_NO_ALIGN_ZERO 1 #else #define VG_MEMALIGN_ALIGN_FACTOR_FOUR 0 +#define VG_MEMALIGN_NO_ALIGN_ZERO 0 #endif #if defined(MUSL_LIBC) @@ -1771,9 +1805,12 @@ extern int * __error(void) __attribute__((weak)); ( SizeT alignment, SizeT n ) \ { \ void* v; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=n, .alloc_kind=AllocKindMemalign}; \ \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE("memalign(al %llu, size %llu)", \ (ULong)alignment, (ULong)n ); \ \ @@ -1784,7 +1821,7 @@ extern int * __error(void) __attribute__((weak)); /* Round up to nearest power-of-two if necessary (like glibc). */ \ while (0 != (alignment & (alignment - 1))) alignment++; \ \ - v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, n ); \ + v = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, alignment, orig_alignment, n ); \ MALLOC_TRACE(" = %p\n", v ); \ if (!v) SET_ERRNO_ENOMEM; \ return v; \ @@ -1792,40 +1829,50 @@ extern int * __error(void) __attribute__((weak)); #else -#define MEMALIGN(soname, fnname) \ - \ - void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ - ( SizeT alignment, SizeT size ); \ - void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \ - ( SizeT alignment, SizeT size ) \ - { \ - void *mem; \ - \ - DO_INIT; \ - MALLOC_TRACE("memalign(alignment %llu, size %llu)", \ - (ULong)alignment, (ULong)size ); \ - if ((VG_MEMALIGN_NO_SIZE_ZERO && (size == 0)) \ - || (VG_MEMALIGN_NO_ALIGN_ZERO && (alignment == 0)) \ - || (VG_MEMALIGN_ALIGN_POWER_TWO && (alignment & (alignment - 1)) != 0) \ - || (VG_MEMALIGN_ALIGN_FACTOR_FOUR && (alignment % 4 != 0))) { \ - SET_ERRNO_EINVAL; \ - return 0; \ - } \ - /* Round up to minimum alignment if necessary. */ \ - if (alignment < VG_MIN_MALLOC_SZB) \ - alignment = VG_MIN_MALLOC_SZB; \ - /* Solaris allows non-power of 2 alignment but not Valgrind. */ \ - while (0 != (alignment & (alignment - 1))) alignment++; \ - \ - if (VG_MEMALIGN_MAKE_SIZE_MULTIPLE_ALIGN) { \ - size = ((size + alignment - 1)/alignment)*alignment; \ - } \ - \ - mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size ); \ - \ - if (!mem) SET_ERRNO_ENOMEM; \ - \ - return mem; \ +#define MEMALIGN(soname, fnname) \ + \ + void* VG_REPLACE_FUNCTION_EZU(10110, soname, fnname)(SizeT alignment, \ + SizeT size); \ + void* VG_REPLACE_FUNCTION_EZU(10110, soname, fnname)(SizeT alignment, \ + SizeT size) \ + { \ + void* mem; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { \ + .orig_alignment = alignment, \ + .size = size, \ + .alloc_kind = AllocKindMemalign}; \ + \ + DO_INIT; \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ + MALLOC_TRACE("memalign(alignment %llu, size %llu)", (ULong)alignment, \ + (ULong)size); \ + if ((VG_MEMALIGN_NO_SIZE_ZERO && (size == 0)) || \ + (VG_MEMALIGN_NO_ALIGN_ZERO && (alignment == 0)) || \ + (VG_MEMALIGN_ALIGN_POWER_TWO && \ + (alignment & (alignment - 1)) != 0) || \ + (VG_MEMALIGN_ALIGN_FACTOR_FOUR && (alignment % 4 != 0))) { \ + SET_ERRNO_EINVAL; \ + return 0; \ + } \ + /* Round up to minimum alignment if necessary. */ \ + if (alignment < VG_MIN_MALLOC_SZB) \ + alignment = VG_MIN_MALLOC_SZB; \ + /* Solaris allows non-power of 2 alignment but not Valgrind. */ \ + while (0 != (alignment & (alignment - 1))) \ + alignment++; \ + \ + if (VG_MEMALIGN_MAKE_SIZE_MULTIPLE_ALIGN) { \ + size = ((size + alignment - 1) / alignment) * alignment; \ + } \ + \ + mem = (void*)VALGRIND_NON_SIMD_CALL3(info.tl_memalign, alignment, \ + orig_alignment, size); \ + \ + if (!mem) \ + SET_ERRNO_ENOMEM; \ + \ + return mem; \ } #endif @@ -1863,8 +1910,8 @@ extern int * __error(void) __attribute__((weak)); pszB = my_getpagesize(); \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ - mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \ - pszB, size ); \ + mem = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, \ + pszB, pszB, size ); \ \ if (!mem) SET_ERRNO_ENOMEM; \ \ @@ -1882,8 +1929,8 @@ extern int * __error(void) __attribute__((weak)); if (pszB == 0) \ pszB = my_getpagesize(); \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED((UWord) zone); \ - return (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \ - pszB, size ); \ + return (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, \ + pszB, pszB, size); \ } #if defined(VGO_linux) @@ -1994,9 +2041,12 @@ extern int * __error(void) __attribute__((weak)); ( void **memptr, SizeT alignment, SizeT size ) \ { \ void *mem; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=size, .alloc_kind=AllocKindPosixMemalign}; \ \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE("posix_memalign(al %llu, size %llu)\n", \ (ULong)alignment, (ULong)size ); \ /* Test whether the alignment argument is valid. It must be \ @@ -2016,8 +2066,8 @@ extern int * __error(void) __attribute__((weak)); if (alignment < VG_MIN_MALLOC_SZB) \ alignment = VG_MIN_MALLOC_SZB; \ \ - mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \ - alignment, size ); \ + mem = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, \ + alignment, orig_alignment, size ); \ \ if (mem != NULL) { \ *memptr = mem; \ @@ -2117,9 +2167,12 @@ extern int * __error(void) __attribute__((weak)); ( SizeT alignment, SizeT size ) \ { \ void *mem; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=size, .alloc_kind=AllocKindAlignedAlloc}; \ \ DO_INIT; \ TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \ (ULong)alignment, (ULong)size ); \ /* Test whether the alignment argument is valid. It must be \ @@ -2129,8 +2182,8 @@ extern int * __error(void) __attribute__((weak)); || (alignment & (alignment - 1)) != 0) \ return 0; \ \ - mem = VG_REPLACE_FUNCTION_EZU(10110,VG_Z_LIBC_SONAME,memalign) \ - (alignment, size); \ + mem = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, \ + alignment, orig_alignment, size ); \ \ return mem; \ } @@ -2145,8 +2198,11 @@ extern int * __error(void) __attribute__((weak)); ( SizeT alignment, SizeT size ) \ { \ void *mem; \ + SizeT orig_alignment = alignment; \ + struct AlignedAllocInfo aligned_alloc_info = { .orig_alignment=alignment, .size=size, .alloc_kind=AllocKindAlignedAlloc}; \ \ DO_INIT; \ + VERIFY_ALIGNMENT(&aligned_alloc_info); \ MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \ (ULong)alignment, (ULong)size ); \ if ((VG_ALIGNED_ALLOC_NO_SIZE_ZERO && (alignment == 0)) \ @@ -2163,8 +2219,8 @@ extern int * __error(void) __attribute__((weak)); /* Solaris allows non-power of 2 alignment but not Valgrind. */ \ while (0 != (alignment & (alignment - 1))) alignment++; \ \ - mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \ - alignment, size ); \ + mem = (void*)VALGRIND_NON_SIMD_CALL3( info.tl_memalign, \ + alignment, orig_alignment, size ); \ \ if (!mem) SET_ERRNO_ENOMEM; \ \ diff --git a/coregrind/m_tooliface.c b/coregrind/m_tooliface.c index 0c33498dbc..de16ebfe88 100644 --- a/coregrind/m_tooliface.c +++ b/coregrind/m_tooliface.c @@ -336,10 +336,10 @@ void VG_(needs_info_location) ( void VG_(needs_malloc_replacement)( void* (*malloc) ( ThreadId, SizeT ), void* (*__builtin_new) ( ThreadId, SizeT ), - void* (*__builtin_new_aligned)( ThreadId, SizeT, SizeT ), + void* (*__builtin_new_aligned)( ThreadId, SizeT, SizeT, SizeT ), void* (*__builtin_vec_new) ( ThreadId, SizeT ), - void* (*__builtin_vec_new_aligned)( ThreadId, SizeT, SizeT ), - void* (*memalign) ( ThreadId, SizeT, SizeT ), + void* (*__builtin_vec_new_aligned)( ThreadId, SizeT, SizeT, SizeT ), + void* (*memalign) ( ThreadId, SizeT, SizeT, SizeT ), void* (*calloc) ( ThreadId, SizeT, SizeT ), void (*free) ( ThreadId, void* ), void (*__builtin_delete) ( ThreadId, void* ), diff --git a/coregrind/pub_core_replacemalloc.h b/coregrind/pub_core_replacemalloc.h index bfd137a8b2..f26884c4fd 100644 --- a/coregrind/pub_core_replacemalloc.h +++ b/coregrind/pub_core_replacemalloc.h @@ -41,10 +41,10 @@ struct vg_mallocfunc_info { void* (*tl_malloc) (ThreadId tid, SizeT n); void* (*tl___builtin_new) (ThreadId tid, SizeT n); - void* (*tl___builtin_new_aligned) (ThreadId tid, SizeT n, SizeT align); + void* (*tl___builtin_new_aligned) (ThreadId tid, SizeT n, SizeT align, SizeT orig_align); void* (*tl___builtin_vec_new) (ThreadId tid, SizeT n); - void* (*tl___builtin_vec_new_aligned) (ThreadId tid, SizeT n, SizeT align); - void* (*tl_memalign) (ThreadId tid, SizeT align, SizeT n); + void* (*tl___builtin_vec_new_aligned) (ThreadId tid, SizeT n, SizeT align, SizeT orig_align); + void* (*tl_memalign) (ThreadId tid, SizeT align, SizeT orig_align, SizeT n); void* (*tl_calloc) (ThreadId tid, SizeT nmemb, SizeT n); void (*tl_free) (ThreadId tid, void* p); void (*tl___builtin_delete) (ThreadId tid, void* p); diff --git a/coregrind/pub_core_tooliface.h b/coregrind/pub_core_tooliface.h index 6b42cc07ec..492c06818f 100644 --- a/coregrind/pub_core_tooliface.h +++ b/coregrind/pub_core_tooliface.h @@ -159,10 +159,10 @@ typedef struct { // VG_(needs).malloc_replacement void* (*tool_malloc) (ThreadId, SizeT); void* (*tool___builtin_new) (ThreadId, SizeT); - void* (*tool___builtin_new_aligned) (ThreadId, SizeT, SizeT); + void* (*tool___builtin_new_aligned) (ThreadId, SizeT, SizeT, SizeT); void* (*tool___builtin_vec_new) (ThreadId, SizeT); - void* (*tool___builtin_vec_new_aligned) (ThreadId, SizeT, SizeT); - void* (*tool_memalign) (ThreadId, SizeT, SizeT); + void* (*tool___builtin_vec_new_aligned) (ThreadId, SizeT, SizeT, SizeT); + void* (*tool_memalign) (ThreadId, SizeT, SizeT, SizeT); void* (*tool_calloc) (ThreadId, SizeT, SizeT); void (*tool_free) (ThreadId, void*); void (*tool___builtin_delete) (ThreadId, void*); diff --git a/dhat/dh_main.c b/dhat/dh_main.c index 24d1c2768b..49cab3193c 100644 --- a/dhat/dh_main.c +++ b/dhat/dh_main.c @@ -763,7 +763,7 @@ static void* dh___builtin_new ( ThreadId tid, SizeT szB ) return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* dh___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +static void* dh___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB, SizeT orig_alignB ) { return new_block( tid, NULL, szB, alignB, /*is_zeroed*/False ); } @@ -773,7 +773,7 @@ static void* dh___builtin_vec_new ( ThreadId tid, SizeT szB ) return new_block( tid, NULL, szB, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* dh___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +static void* dh___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB, SizeT orig_alignB ) { return new_block( tid, NULL, szB, alignB, /*is_zeroed*/False ); } @@ -783,7 +783,7 @@ static void* dh_calloc ( ThreadId tid, SizeT m, SizeT szB ) return new_block( tid, NULL, m*szB, VG_(clo_alignment), /*is_zeroed*/True ); } -static void *dh_memalign ( ThreadId tid, SizeT alignB, SizeT szB ) +static void *dh_memalign ( ThreadId tid, SizeT alignB, SizeT orig_alignB, SizeT szB) { return new_block( tid, NULL, szB, alignB, False ); } diff --git a/drd/drd_malloc_wrappers.c b/drd/drd_malloc_wrappers.c index b1be605832..72e9061818 100644 --- a/drd/drd_malloc_wrappers.c +++ b/drd/drd_malloc_wrappers.c @@ -147,7 +147,7 @@ static void* drd_malloc(ThreadId tid, SizeT n) } /** Wrapper for memalign(). */ -static void* drd_memalign(ThreadId tid, SizeT align, SizeT n) +static void* drd_memalign(ThreadId tid, SizeT align, SizeT orig_alignT, SizeT n) { return new_block(tid, n, align, /*is_zeroed*/False); } @@ -258,7 +258,7 @@ static void* drd___builtin_new(ThreadId tid, SizeT n) } /** Wrapper for __builtin_new_aligned(). */ -static void* drd___builtin_new_aligned(ThreadId tid, SizeT n, SizeT align) +static void* drd___builtin_new_aligned(ThreadId tid, SizeT n, SizeT align, SizeT orig_align) { return new_block(tid, n, align, /*is_zeroed*/False); } @@ -282,7 +282,7 @@ static void* drd___builtin_vec_new(ThreadId tid, SizeT n) } /** Wrapper for __builtin_vec_new_aligned(). */ -static void* drd___builtin_vec_new_aligned(ThreadId tid, SizeT n, SizeT align) +static void* drd___builtin_vec_new_aligned(ThreadId tid, SizeT n, SizeT align, SizeT orig_align) { return new_block(tid, n, align, /*is_zeroed*/False); } diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index cebc2bd2a1..b193d07d62 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -4237,7 +4237,7 @@ static void* hg_cli____builtin_new ( ThreadId tid, SizeT n ) { return handle_alloc ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* hg_cli____builtin_new_aligned ( ThreadId tid, SizeT n, SizeT align ) { +static void* hg_cli____builtin_new_aligned ( ThreadId tid, SizeT n, SizeT align, SizeT orig_align ) { if (((SSizeT)n) < 0) return NULL; return handle_alloc ( tid, n, align, /*is_zeroed*/False ); @@ -4247,12 +4247,12 @@ static void* hg_cli____builtin_vec_new ( ThreadId tid, SizeT n ) { return handle_alloc ( tid, n, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* hg_cli____builtin_vec_new_aligned ( ThreadId tid, SizeT n, SizeT align ) { +static void* hg_cli____builtin_vec_new_aligned ( ThreadId tid, SizeT n, SizeT align, SizeT orig_align ) { if (((SSizeT)n) < 0) return NULL; return handle_alloc ( tid, n, align, /*is_zeroed*/False ); } -static void* hg_cli__memalign ( ThreadId tid, SizeT align, SizeT n ) { +static void* hg_cli__memalign ( ThreadId tid, SizeT align, SizeT orig_alignT, SizeT n ) { if (((SSizeT)n) < 0) return NULL; return handle_alloc ( tid, n, align, /*is_zeroed*/False ); diff --git a/include/pub_tool_replacemalloc.h b/include/pub_tool_replacemalloc.h index d59027f3e2..41c51eeb36 100644 --- a/include/pub_tool_replacemalloc.h +++ b/include/pub_tool_replacemalloc.h @@ -80,6 +80,37 @@ extern Bool VG_(replacement_malloc_process_cmd_line_option) ( const HChar* arg ) // been called. extern SizeT VG_(malloc_effective_client_redzone_size)(void); +/* We have 4 different C functions that perform aligned allocation + * They all have slightly different error conditions. But we only have + * one wrapper - tl_memalign. Rather than split that into four + * nearly identical functions (or resort to a lot of client + * requests), the following enum and struct add context so that + * memcheck can figure out whether to emit an error. + * This isn't a problem for the C++ allocators. Even though + * there are many of them they all have the same alignment + * behaviour. */ + +typedef enum { + AllocKindMemalign, + AllocKindPosixMemalign, + AllocKindAlignedAlloc, + AllocKindDeleteSized, + AllocKindVecDeleteSized, + AllocKindNewAligned, + AllocKindVecNewAligned, + AllocKindDeleteAligned, + AllocKindVecDeleteAligned, + AllocKindDeleteSizedAligned, + AllocKindVecDeleteSizedAligned +} AlignedAllocKind; + +struct AlignedAllocInfo { + SizeT orig_alignment; + SizeT size; + void *mem; + AlignedAllocKind alloc_kind; +}; + #endif // __PUB_TOOL_REPLACEMALLOC_H /*--------------------------------------------------------------------*/ diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h index 34e577fce6..6031d13286 100644 --- a/include/pub_tool_tooliface.h +++ b/include/pub_tool_tooliface.h @@ -474,10 +474,10 @@ extern void VG_(needs_var_info) ( void ); extern void VG_(needs_malloc_replacement)( void* (*pmalloc) ( ThreadId tid, SizeT n ), void* (*p__builtin_new) ( ThreadId tid, SizeT n ), - void* (*p__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT align ), + void* (*p__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT align, SizeT orig_align ), void* (*p__builtin_vec_new) ( ThreadId tid, SizeT n ), - void* (*p__builtin_vec_new_aligned)( ThreadId tid, SizeT n, SizeT align ), - void* (*pmemalign) ( ThreadId tid, SizeT align, SizeT n ), + void* (*p__builtin_vec_new_aligned)( ThreadId tid, SizeT n, SizeT align, SizeT orig_align ), + void* (*pmemalign) ( ThreadId tid, SizeT align, SizeT orig_align, SizeT n), void* (*pcalloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ), void (*pfree) ( ThreadId tid, void* p ), void (*p__builtin_delete) ( ThreadId tid, void* p ), diff --git a/massif/ms_main.c b/massif/ms_main.c index 1040ad53f4..0957349a0a 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -1428,7 +1428,7 @@ static void* ms___builtin_new ( ThreadId tid, SizeT szB ) return alloc_and_record_block( tid, szB, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* ms___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +static void* ms___builtin_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB , SizeT orig_alignB ) { return alloc_and_record_block( tid, szB, alignB, /*is_zeroed*/False ); } @@ -1438,7 +1438,7 @@ static void* ms___builtin_vec_new ( ThreadId tid, SizeT szB ) return alloc_and_record_block( tid, szB, VG_(clo_alignment), /*is_zeroed*/False ); } -static void* ms___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB ) +static void* ms___builtin_vec_new_aligned ( ThreadId tid, SizeT szB, SizeT alignB, SizeT orig_alignB ) { return alloc_and_record_block( tid, szB, alignB, /*is_zeroed*/False ); } @@ -1448,7 +1448,7 @@ static void* ms_calloc ( ThreadId tid, SizeT m, SizeT szB ) return alloc_and_record_block( tid, m*szB, VG_(clo_alignment), /*is_zeroed*/True ); } -static void *ms_memalign ( ThreadId tid, SizeT alignB, SizeT szB ) +static void *ms_memalign ( ThreadId tid, SizeT alignB, SizeT orig_alignB, SizeT szB) { return alloc_and_record_block( tid, szB, alignB, False ); } diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index 414c3a2393..aa9210f17f 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -36,6 +36,9 @@ problems that are common in C and C++ programs. malloc/new/new[] versus free/delete/delete[] + Mismatches will also be reported for sized and aligned + allocation and deallocation functions if the deallocation value + does not match the allocation value. @@ -56,6 +59,11 @@ problems that are common in C and C++ programs. with realloc. + + Using an alignment value that + is not a power of two. + + Memory leaks. @@ -415,11 +423,13 @@ is checked for being fishy: calloc, realloc, memalign, +posix_memalign, +aligned_alloc, new, new []. __builtin_new, __builtin_vec_new, -For calloc both arguments are being checked. +For calloc both arguments are checked. For example: @@ -458,6 +468,52 @@ the non-portable use or realloc. + +Alignment Errors + +C and C++ have several functions that allow the user to obtain aligned memory. +Typically this is done for performance reasons so that the memory will be cache line +or memory page aligned. C has the functions memalign, +posix_memalign and aligned_alloc. +C++ has numerous overloads of operator new and +operator delete. Of these, posix_memalign is quite clearly +specified, the others vary quite widely between implementations. Valgrind will generate +errors for values of alignment that are invalid on any platform. + + +memalign will produce errors if the alignment +is zero or not a multiple of two. + +posix_memalign will produce errors if the alignment +is less than sizeof(size_t), not a multiple of two or if the size is zero. + +aligned_alloc will produce errors if the alignment +is not a multiple of two , if the size is zero or if the size is not an integral +multiple of the alignment. + +aligned new will produce errors if the alignment +is zero or not a multiple of two. The nothrow overloads +will return a NULL pointer. The non-nothrow overloads will abort Valgrind. + +aligned delete will produce errors if the alignment +is zero or not a multiple of two or if the alignment is not the same as that used by +aligned new. + +sized delete will produce errors if the size +is not the same as that used by new. + +sized aligned delete combines the error conditions +of the individual sized and aligned delete operators. + +Example output: + + + Memory leak detection diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c index 65210a2209..2a4cce7a11 100644 --- a/memcheck/mc_errors.c +++ b/memcheck/mc_errors.c @@ -76,6 +76,10 @@ typedef Err_IllegalMempool, Err_FishyValue, Err_ReallocSizeZero, + Err_BadAlign, + Err_BadSize, + Err_SizeMismatch, + Err_AlignMismatch, } MC_ErrorTag; @@ -164,6 +168,19 @@ struct _MC_Error { AddrInfo ai; } ReallocSizeZero; + struct { + AddrInfo ai; + SizeT dealloc_align; + SizeT size; + const HChar *msg; + } BadAlign; + + struct { + AddrInfo ai; + SizeT size; + const HChar *func; + } BadSize; + // Call to strcpy, memcpy, etc, with overlapping blocks. struct { Addr src; // Source block @@ -192,6 +209,25 @@ struct _MC_Error { const HChar *argument_name; SizeT value; } FishyValue; + + // Program allocates heap block with new but + // deallocates with a matching delete + // but with a different size + struct { + AddrInfo ai; + const HChar *function_names; + SizeT size; + } SizeMismatch; + + // Program allocates heap block with one function + // (malloc/new/new[]/custom) and deallocates with + // a matching one but different alignment + struct { + AddrInfo ai; + const HChar *function_names; + SizeT alloc_align; + SizeT dealloc_align; + } AlignMismatch; } Err; }; @@ -719,21 +755,96 @@ void MC_(pp_Error) ( const Error* err ) } break; - case Err_ReallocSizeZero: + case Err_ReallocSizeZero: + if (xml) { + emit( " ReallocSizeZero\n" ); + emit( " realloc() with size 0\n" ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.ReallocSizeZero.ai, False); + } else { + emit( "realloc() with size 0\n" ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.ReallocSizeZero.ai, False); + } + break; + + case Err_BadAlign: + if (extra->Err.BadAlign.size) { + if (xml) { + emit( " InvalidSizeAndAlignment\n" ); + emit( " Invalid size value: %lu alignment value: %lu%s\n", + extra->Err.BadAlign.size, + extra->Err.BadAlign.dealloc_align, extra->Err.BadAlign.msg ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + } else { + emit( "Invalid size value: %lu alignment value: %lu%s\n", + extra->Err.BadAlign.size, + extra->Err.BadAlign.dealloc_align, extra->Err.BadAlign.msg ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + } + } else { + if (xml) { + emit( " InvalidAlignment\n" ); + emit( " Invalid alignment value: %lu%s\n", + extra->Err.BadAlign.dealloc_align, extra->Err.BadAlign.msg ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + } else { + emit( "Invalid alignment value: %lu%s\n", + extra->Err.BadAlign.dealloc_align, extra->Err.BadAlign.msg ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + } + } + break; + + case Err_BadSize: if (xml) { - emit( " ReallocSizeZero\n" ); - emit( " realloc() with size 0\n" ); + emit( " InvalidSize\n" ); + emit( " %s invalid size value: %lu\n", + extra->Err.BadSize.func, extra->Err.BadSize.size ); VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), - &extra->Err.ReallocSizeZero.ai, False); } else { - emit( "realloc() with size 0\n" ); + emit( "%s invalid size value: %lu\n", + extra->Err.BadSize.func, extra->Err.BadSize.size ); VG_(pp_ExeContext)( VG_(get_error_where)(err) ); - VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), - &extra->Err.ReallocSizeZero.ai, False); } break; + case Err_SizeMismatch: + if (xml) { + emit( " MismatchedAllocateDeallocateSize\n" ); + emit( " Mismatched %s size value: %lu\n", + extra->Err.SizeMismatch.function_names, extra->Err.SizeMismatch.size ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.SizeMismatch.ai, False); + } else { + emit( "Mismatched %s size value: %lu\n", + extra->Err.SizeMismatch.function_names, extra->Err.SizeMismatch.size ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.SizeMismatch.ai, False); + } + break; + + case Err_AlignMismatch: + if (xml) { + emit( " MismatchedAllocateDeallocateAlignment\n" ); + emit( " Mismatched %s size alloc value: %lu dealloc value %lu\n", + extra->Err.SizeMismatch.function_names, extra->Err.AlignMismatch.alloc_align, extra->Err.AlignMismatch.dealloc_align ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.AlignMismatch.ai, False); + } else { + emit( "Mismatched %s alignment alloc value: %lu dealloc value: %lu\n", + extra->Err.AlignMismatch.function_names, extra->Err.AlignMismatch.alloc_align, extra->Err.AlignMismatch.dealloc_align ); + VG_(pp_ExeContext)( VG_(get_error_where)(err) ); + VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), + &extra->Err.AlignMismatch.ai, False); + } + break; + default: VG_(printf)("Error:\n unknown Memcheck error code %d\n", VG_(get_error_kind)(err)); @@ -896,6 +1007,24 @@ void MC_(record_realloc_size_zero) ( ThreadId tid, Addr a ) VG_(maybe_record_error)( tid, Err_ReallocSizeZero, a, /*s*/NULL, &extra ); } +void MC_(record_bad_alignment) ( ThreadId tid, SizeT align, SizeT size, const HChar *msg ) +{ + MC_Error extra; + tl_assert(VG_INVALID_THREADID != tid); + extra.Err.BadAlign.dealloc_align = align; + extra.Err.BadAlign.size= size; + extra.Err.BadAlign.msg = msg; + VG_(maybe_record_error)( tid, Err_BadAlign, /*addr*/0, /*s*/NULL, &extra ); +} + +void MC_(record_bad_size) ( ThreadId tid, SizeT size, const HChar *function ) +{ + MC_Error extra; + tl_assert(VG_INVALID_THREADID != tid); + extra.Err.BadSize.size= size; + extra.Err.BadSize.func = function; + VG_(maybe_record_error)( tid, Err_BadSize, /*addr*/0, /*s*/NULL, &extra ); +} void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a ) { @@ -950,6 +1079,45 @@ Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name, return True; } +void MC_(record_size_mismatch_error) ( ThreadId tid, MC_Chunk* mc, SizeT size, const HChar *function_names) +{ + MC_Error extra; + AddrInfo* ai = &extra.Err.SizeMismatch.ai; + tl_assert(VG_INVALID_THREADID != tid); + ai->tag = Addr_Block; + ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed' + ai->Addr.Block.block_desc = "block"; + ai->Addr.Block.block_szB = mc->szB; + ai->Addr.Block.rwoffset = 0; + ai->Addr.Block.allocated_at = MC_(allocated_at) (mc); + VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); + ai->Addr.Block.freed_at = MC_(freed_at) (mc); + extra.Err.SizeMismatch.size = size; + extra.Err.SizeMismatch.function_names = function_names; + VG_(maybe_record_error)( tid, Err_SizeMismatch, mc->data, /*s*/NULL, + &extra ); +} + +void MC_(record_align_mismatch_error) ( ThreadId tid, MC_Chunk* mc, SizeT align, const HChar *function_names ) +{ + MC_Error extra; + AddrInfo* ai = &extra.Err.AlignMismatch.ai; + tl_assert(VG_INVALID_THREADID != tid); + ai->tag = Addr_Block; + ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed' + ai->Addr.Block.block_desc = "block"; + ai->Addr.Block.block_szB = mc->szB; + ai->Addr.Block.rwoffset = 0; + ai->Addr.Block.allocated_at = MC_(allocated_at) (mc); + VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); + ai->Addr.Block.freed_at = MC_(freed_at) (mc); + extra.Err.AlignMismatch.alloc_align = mc->alignB; + extra.Err.AlignMismatch.dealloc_align = align; + extra.Err.AlignMismatch.function_names = function_names; + VG_(maybe_record_error)( tid, Err_AlignMismatch, mc->data, /*s*/NULL, + &extra ); +} + void MC_(record_user_error) ( ThreadId tid, Addr a, Bool isAddrErr, UInt otag ) { @@ -1058,6 +1226,38 @@ Bool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 ) return ( extra1->Err.Value.szB == extra2->Err.Value.szB ? True : False ); + case Err_BadAlign: + if (extra1->Err.BadAlign.size && + extra2->Err.BadAlign.size) { + // cases where size should be non-zero or a multiple of alignment + return extra1->Err.BadAlign.size == + extra2->Err.BadAlign.size + && + extra1->Err.BadAlign.dealloc_align == + extra2->Err.BadAlign.dealloc_align; + } else { + // non multiple of 2 alignment + return extra1->Err.BadAlign.dealloc_align == + extra2->Err.BadAlign.dealloc_align; + } + + case Err_BadSize: + // sized delete mismatch + return extra1->Err.BadSize.size == + extra2->Err.BadSize.size; + + case Err_SizeMismatch: + return extra1->Err.SizeMismatch.size == + extra2->Err.SizeMismatch.size; + + case Err_AlignMismatch: + // alignments both powers of 2 but different + return extra1->Err.AlignMismatch.alloc_align == + extra2->Err.AlignMismatch.alloc_align + && + extra1->Err.AlignMismatch.dealloc_align == + extra2->Err.AlignMismatch.dealloc_align; + case Err_Leak: VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n" "since it's handled with VG_(unique_error)()!"); @@ -1202,6 +1402,10 @@ UInt MC_(update_Error_extra)( const Error* err ) // shown with VG_(unique_error)() so they 'extra' not copied. But // we make it consistent with the others. case Err_Leak: + case Err_BadAlign: + case Err_BadSize: + case Err_SizeMismatch: + case Err_AlignMismatch: return sizeof(MC_Error); // For value errors, get the ExeContext corresponding to the @@ -1352,13 +1556,17 @@ typedef // Unaddressable read/write attempt at given size Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp, - JumpSupp, // Jump to unaddressable target - FreeSupp, // Invalid or mismatching free - OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc - LeakSupp, // Something to be suppressed in a leak check. - MempoolSupp, // Memory pool suppression. - FishyValueSupp,// Fishy value suppression. - ReallocSizeZeroSupp, // realloc size 0 suppression + JumpSupp, // Jump to unaddressable target + FreeSupp, // Invalid or mismatching free + OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc + LeakSupp, // Something to be suppressed in a leak check. + MempoolSupp, // Memory pool suppression. + FishyValueSupp, // Fishy value suppression. + ReallocSizeZeroSupp, // realloc size 0 suppression + BadAlignSupp, // Alignment not 2 + BadSizeSupp, // aligned alloc with size 0 + SizeMismatch, // Sized deallocation did not match allocation size + AlignMismatch, // Aligned deallocation did not match aligned allocation } MC_SuppKind; @@ -1390,6 +1598,10 @@ Bool MC_(is_recognised_suppression) ( const HChar* name, Supp* su ) else if (VG_STREQ(name, "Value32")) skind = Value32Supp; else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp; else if (VG_STREQ(name, "ReallocZero")) skind = ReallocSizeZeroSupp; + else if (VG_STREQ(name, "BadAlign")) skind = BadAlignSupp; + else if (VG_STREQ(name, "BadSize")) skind = BadSizeSupp; + else if (VG_STREQ(name, "SizeMismatch")) skind = SizeMismatch; + else if (VG_STREQ(name, "AlignMismatch")) skind = AlignMismatch; else return False; @@ -1567,10 +1779,20 @@ Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su ) supp_extra->argument_name); } - case ReallocSizeZeroSupp: { - + case ReallocSizeZeroSupp: return (ekind == Err_ReallocSizeZero); - } + + case BadAlignSupp: + return (ekind == Err_BadAlign); + + case BadSizeSupp: + return (ekind == Err_BadSize); + + case SizeMismatch: + return (ekind == Err_SizeMismatch); + + case AlignMismatch: + return (ekind = Err_AlignMismatch); default: VG_(printf)("Error:\n" @@ -1597,6 +1819,10 @@ const HChar* MC_(get_error_name) ( const Error* err ) case Err_Cond: return "Cond"; case Err_FishyValue: return "FishyValue"; case Err_ReallocSizeZero: return "ReallocZero"; + case Err_BadAlign: return "BadAlign"; + case Err_BadSize: return "BadSize"; + case Err_SizeMismatch: return "SizeMismatch"; + case Err_AlignMismatch: return "AlignMismatch"; case Err_Addr: { MC_Error* extra = VG_(get_error_extra)(err); switch ( extra->Err.Addr.szB ) { diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index c30ec48efb..e068f49db9 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -65,6 +65,7 @@ typedef Addr data; // Address of the actual block. SizeT szB : (sizeof(SizeT)*8)-2; // Size requested; 30 or 62 bits. MC_AllocKind allockind : 2; // Which operation did the allocation. + SizeT alignB; // Alignment (if requested) of the allocation ExeContext* where[0]; /* Variable-length array. The size depends on MC_(clo_keep_stacktraces). This array optionally stores the alloc and/or free stack trace. */ @@ -101,6 +102,7 @@ typedef void* MC_(new_block) ( ThreadId tid, Addr p, SizeT size, SizeT align, + SizeT orig_align, Bool is_zeroed, MC_AllocKind kind, VgHashTable *table); void MC_(handle_free) ( ThreadId tid, @@ -150,10 +152,10 @@ SizeT MC_(get_cmalloc_n_frees) ( void ); void* MC_(malloc) ( ThreadId tid, SizeT n ); void* MC_(__builtin_new) ( ThreadId tid, SizeT n ); -void* MC_(__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT alignB ); +void* MC_(__builtin_new_aligned)( ThreadId tid, SizeT n, SizeT alignB, SizeT orig_alignB ); void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n ); -void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ); -void* MC_(memalign) ( ThreadId tid, SizeT align, SizeT n ); +void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB, SizeT orig_alignB ); +void* MC_(memalign) ( ThreadId tid, SizeT align, SizeT orig_alignB, SizeT n); void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ); void MC_(free) ( ThreadId tid, void* p ); void MC_(__builtin_delete) ( ThreadId tid, void* p ); @@ -556,6 +558,8 @@ void MC_(record_free_error) ( ThreadId tid, Addr a ); void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a ); void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc ); void MC_(record_realloc_size_zero) ( ThreadId tid, Addr a ); +void MC_(record_bad_alignment) ( ThreadId tid, SizeT align, SizeT size, const HChar *msg); +void MC_(record_bad_size) ( ThreadId tid, SizeT align, const HChar *function); void MC_(record_overlap_error) ( ThreadId tid, const HChar* function, Addr src, Addr dst, SizeT szB ); @@ -575,6 +579,9 @@ Bool MC_(record_leak_error) ( ThreadId tid, Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar* function, const HChar *argument_name, SizeT value ); +void MC_(record_size_mismatch_error) ( ThreadId tid, MC_Chunk* mc, SizeT size, const HChar *function_names ); +void MC_(record_align_mismatch_error) ( ThreadId tid, MC_Chunk* mc, SizeT align, const HChar *function_names ); + /* Leak kinds tokens to call VG_(parse_enum_set). */ extern const HChar* MC_(parse_leak_kinds_tokens); diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 946813be79..90b89a9115 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -6981,6 +6981,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret ) { Int i; Addr bad_addr; + MC_Chunk* mc = NULL; if (!VG_IS_TOOL_USERREQ('M','C',arg[0]) && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0] @@ -7178,7 +7179,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret ) UInt rzB = arg[3]; Bool is_zeroed = (Bool)arg[4]; - MC_(new_block) ( tid, p, sizeB, /*ignored*/0, is_zeroed, + MC_(new_block) ( tid, p, sizeB, /*ignored*/0U, 0U, is_zeroed, MC_AllocCustom, MC_(malloc_list) ); if (rzB > 0) { MC_(make_mem_noaccess) ( p - rzB, rzB); @@ -7212,6 +7213,126 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret ) return True; } + case _VG_USERREQ__MEMCHECK_VERIFY_ALIGNMENT: { + struct AlignedAllocInfo *aligned_alloc_info = (struct AlignedAllocInfo *)arg[1]; + tl_assert(aligned_alloc_info); + + switch (aligned_alloc_info->alloc_kind) { + case AllocKindMemalign: + // other platforms just ensure it is a power of 2 + // ignore Illumos only enforcing multiple of 4 (probably a bug) + if (aligned_alloc_info->orig_alignment == 0U || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be power of 2)" ); + } + // size zero not allowed on all platforms (e.g. Illumos) + if (aligned_alloc_info->size == 0) { + MC_(record_bad_size) ( tid, aligned_alloc_info->size, "memalign()" ); + } + break; + case AllocKindPosixMemalign: + // must be power of 2 + // alignment at least sizeof(size_t) + // size of 0 implementation defined + if (aligned_alloc_info->orig_alignment < sizeof(SizeT) || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero, a power of 2 and a multiple of sizeof(void*))" ); + } + if (aligned_alloc_info->size == 0) { + MC_(record_bad_size) ( tid, aligned_alloc_info->size, "posix_memalign()" ); + } + break; + case AllocKindAlignedAlloc: + // must be power of 2 + if ((aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be a power of 2)" ); + } + // size should be integral multiple of alignment + if (aligned_alloc_info->orig_alignment && + aligned_alloc_info->size % aligned_alloc_info->orig_alignment != 0U) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , aligned_alloc_info->size, " (size should be a multiple of alignment)" ); + } + if (aligned_alloc_info->size == 0) { + MC_(record_bad_size) ( tid, aligned_alloc_info->size, "aligned_alloc()" ); + } + break; + case AllocKindDeleteSized: + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "new/delete" ); + } + break; + case AllocKindVecDeleteSized: + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "new[][/delete[]" ); + } + break; + case AllocKindNewAligned: + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + break; + case AllocKindVecNewAligned: + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + break; + case AllocKindDeleteAligned: + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && aligned_alloc_info->orig_alignment != mc->alignB) { + MC_(record_align_mismatch_error) ( tid, mc, aligned_alloc_info->orig_alignment, "new/delete"); + } + break; + case AllocKindVecDeleteAligned: + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && aligned_alloc_info->orig_alignment != mc->alignB) { + MC_(record_align_mismatch_error) ( tid, mc, aligned_alloc_info->orig_alignment, "new[]/delete[]"); + } + break; + case AllocKindDeleteSizedAligned: + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "new/delete"); + } + if (aligned_alloc_info->orig_alignment != mc->alignB) { + MC_(record_align_mismatch_error) ( tid, mc, aligned_alloc_info->orig_alignment, "new/delete"); + } + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + break; + case AllocKindVecDeleteSizedAligned: + mc = VG_(HT_lookup) ( MC_(malloc_list), (UWord)aligned_alloc_info->mem ); + if (mc && mc->szB != aligned_alloc_info->size) { + MC_(record_size_mismatch_error) ( tid, mc, aligned_alloc_info->size, "new[]/delete[]" ); + } + if (aligned_alloc_info->orig_alignment != mc->alignB) { + MC_(record_align_mismatch_error) ( tid, mc, aligned_alloc_info->orig_alignment, "new[]/delete[]"); + } + if (aligned_alloc_info->orig_alignment == 0 || + (aligned_alloc_info->orig_alignment & (aligned_alloc_info->orig_alignment - 1)) != 0) { + MC_(record_bad_alignment) ( tid, aligned_alloc_info->orig_alignment , 0U, " (should be non-zero and a power of 2)" ); + } + break; + default: + tl_assert (False); + } + + return True; + } + case VG_USERREQ__CREATE_MEMPOOL: { Addr pool = (Addr)arg[1]; UInt rzB = arg[2]; diff --git a/memcheck/mc_malloc_wrappers.c b/memcheck/mc_malloc_wrappers.c index 87cf4d8f54..f2fe1f74c6 100644 --- a/memcheck/mc_malloc_wrappers.c +++ b/memcheck/mc_malloc_wrappers.c @@ -78,6 +78,7 @@ VgHashTable *MC_(mempool_list) = NULL; PoolAlloc *MC_(chunk_poolalloc) = NULL; static MC_Chunk* create_MC_Chunk ( ThreadId tid, Addr p, SizeT szB, + SizeT alignB, MC_AllocKind kind); static inline void delete_MC_Chunk (MC_Chunk* mc); @@ -186,15 +187,21 @@ MC_Chunk* MC_(get_freed_block_bracketting) (Addr a) return NULL; } +// @todo PJF !!!!!!!!!! +// below alignB is the cleanup up value +// would prefer the original value !!!!!!!!! + /* Allocate a shadow chunk, put it on the appropriate list. If needed, release oldest blocks from freed list. */ static MC_Chunk* create_MC_Chunk ( ThreadId tid, Addr p, SizeT szB, + SizeT alignB, MC_AllocKind kind) { MC_Chunk* mc = VG_(allocEltPA)(MC_(chunk_poolalloc)); mc->data = p; mc->szB = szB; + mc->alignB = alignB; mc->allockind = kind; switch ( MC_(n_where_pointers)() ) { case 2: mc->where[1] = 0; // fallthrough to 1 @@ -357,6 +364,7 @@ UInt MC_(n_where_pointers) (void) /* Allocate memory and note change in memory available */ void* MC_(new_block) ( ThreadId tid, Addr p, SizeT szB, SizeT alignB, + SizeT orig_alignB, Bool is_zeroed, MC_AllocKind kind, VgHashTable *table) { @@ -383,7 +391,7 @@ void* MC_(new_block) ( ThreadId tid, // Only update stats if allocation succeeded. cmalloc_n_mallocs ++; cmalloc_bs_mallocd += (ULong)szB; - mc = create_MC_Chunk (tid, p, szB, kind); + mc = create_MC_Chunk (tid, p, szB, orig_alignB, kind); VG_(HT_add_node)( table, mc ); if (is_zeroed) @@ -402,7 +410,7 @@ void* MC_(malloc) ( ThreadId tid, SizeT n ) if (MC_(record_fishy_value_error)(tid, "malloc", "size", n)) { return NULL; } else { - return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), + return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), 0U, /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list)); } } @@ -412,17 +420,17 @@ void* MC_(__builtin_new) ( ThreadId tid, SizeT n ) if (MC_(record_fishy_value_error)(tid, "__builtin_new", "size", n)) { return NULL; } else { - return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), + return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), 0U, /*is_zeroed*/False, MC_AllocNew, MC_(malloc_list)); } } -void* MC_(__builtin_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ) +void* MC_(__builtin_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB, SizeT orig_alignB ) { if (MC_(record_fishy_value_error)(tid, "__builtin_new_aligned", "size", n)) { return NULL; } else { - return MC_(new_block) ( tid, 0, n, alignB, + return MC_(new_block) ( tid, 0, n, alignB, orig_alignB, /*is_zeroed*/False, MC_AllocNew, MC_(malloc_list)); } } @@ -432,29 +440,29 @@ void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n ) if (MC_(record_fishy_value_error)(tid, "__builtin_vec_new", "size", n)) { return NULL; } else { - return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), + return MC_(new_block) ( tid, 0, n, VG_(clo_alignment), 0U, /*is_zeroed*/False, MC_AllocNewVec, MC_(malloc_list)); } } -void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB ) +void* MC_(__builtin_vec_new_aligned) ( ThreadId tid, SizeT n, SizeT alignB, SizeT orig_alignB ) { if (MC_(record_fishy_value_error)(tid, "__builtin_vec_new_aligned", "size", n)) { return NULL; } else { - return MC_(new_block) ( tid, 0, n, alignB, + return MC_(new_block) ( tid, 0, n, alignB, orig_alignB, /*is_zeroed*/False, MC_AllocNewVec, MC_(malloc_list)); } } -void* MC_(memalign) ( ThreadId tid, SizeT alignB, SizeT n ) +void* MC_(memalign) ( ThreadId tid, SizeT alignB, SizeT orig_alignB, SizeT n) { if (MC_(record_fishy_value_error)(tid, "memalign", "size", n)) { return NULL; - } else { - return MC_(new_block) ( tid, 0, n, alignB, - /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list)); } + + return MC_(new_block) ( tid, 0, n, alignB, orig_alignB, + /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list)); } void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ) @@ -463,7 +471,7 @@ void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 ) MC_(record_fishy_value_error)(tid, "calloc", "size", size1)) { return NULL; } else { - return MC_(new_block) ( tid, 0, nmemb*size1, VG_(clo_alignment), + return MC_(new_block) ( tid, 0, nmemb*size1, VG_(clo_alignment), 0U, /*is_zeroed*/True, MC_AllocMalloc, MC_(malloc_list)); } } @@ -574,7 +582,7 @@ void* MC_(realloc) ( ThreadId tid, void* p_old, SizeT new_szB ) return NULL; if (p_old == NULL) { - return MC_(new_block) ( tid, 0, new_szB, VG_(clo_alignment), + return MC_(new_block) ( tid, 0, new_szB, VG_(clo_alignment), 0U, /*is_zeroed*/False, MC_AllocMalloc, MC_(malloc_list)); } @@ -627,7 +635,8 @@ void* MC_(realloc) ( ThreadId tid, void* p_old, SizeT new_szB ) queue). */ // Allocate a new chunk. - new_mc = create_MC_Chunk( tid, a_new, new_szB, MC_AllocMalloc ); + // Re-allocation does not conserve alignment. + new_mc = create_MC_Chunk( tid, a_new, new_szB, 0U, MC_AllocMalloc ); // Now insert the new mc (with a new 'data' field) into malloc_list. VG_(HT_add_node)( MC_(malloc_list), new_mc ); @@ -959,7 +968,7 @@ void MC_(mempool_alloc)(ThreadId tid, Addr pool, Addr addr, SizeT szB) MC_(record_illegal_mempool_error) ( tid, pool ); } else { if (MP_DETAILED_SANITY_CHECKS) check_mempool_sane(mp); - MC_(new_block)(tid, addr, szB, /*ignored*/0, mp->is_zeroed, + MC_(new_block)(tid, addr, szB, /*ignored*/0U, 0U, mp->is_zeroed, MC_AllocCustom, mp->chunks); if (mp->rzB > 0) { // This is not needed if the user application has properly diff --git a/memcheck/memcheck.h b/memcheck/memcheck.h index 53700542c6..6a71a25666 100644 --- a/memcheck/memcheck.h +++ b/memcheck/memcheck.h @@ -101,7 +101,8 @@ typedef /* This is just for memcheck's internal use - don't use it */ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR - = VG_USERREQ_TOOL_BASE('M','C') + 256 + = VG_USERREQ_TOOL_BASE('M','C') + 256, + _VG_USERREQ__MEMCHECK_VERIFY_ALIGNMENT } Vg_MemCheckClientRequest; diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 687dc6995e..24b39099a7 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -83,7 +83,9 @@ dist_noinst_SCRIPTS = \ filter_malloc_free \ filter_size_t \ filter_stanza \ - filter_stanza.awk + filter_stanza.awk \ + filter_used_supp \ + filter_stanza_and_size_t noinst_HEADERS = leak.h @@ -145,8 +147,36 @@ EXTRA_DIST = \ cxx17_aligned_new.stdout.exp \ sized_aligned_new_delete_args.stderr.exp \ sized_aligned_new_delete_args.vgtest \ - sized_aligned_new_delete_misaligned.stderr.exp \ - sized_aligned_new_delete_misaligned.vgtest \ + sized_aligned_new_delete_misaligned1.stderr.exp \ + sized_aligned_new_delete_misaligned1.vgtest \ + sized_aligned_new_delete_misaligned2.stderr.exp \ + sized_aligned_new_delete_misaligned2.vgtest \ + sized_aligned_new_delete_misaligned3.stderr.exp \ + sized_aligned_new_delete_misaligned3.vgtest \ + sized_aligned_new_delete_misaligned1_xml.stderr.exp \ + sized_aligned_new_delete_misaligned1_xml.vgtest \ + sized_aligned_new_delete_misaligned2_xml.stderr.exp \ + sized_aligned_new_delete_misaligned2_xml.vgtest \ + sized_aligned_new_delete_misaligned3_xml.stderr.exp \ + sized_aligned_new_delete_misaligned3_xml.vgtest \ + sized_aligned_new_delete_misaligned1_supp.vgtest \ + sized_aligned_new_delete_misaligned1_supp.supp \ + sized_aligned_new_delete_misaligned1_supp.stderr.exp \ + sized_aligned_new_delete_misaligned1_supp.stderr.exp_32 \ + sized_aligned_new_delete_misaligned2_supp.vgtest \ + sized_aligned_new_delete_misaligned2_supp.supp \ + sized_aligned_new_delete_misaligned2_supp.stderr.exp \ + sized_aligned_new_delete_misaligned2_supp.stderr.exp_32 \ + sized_aligned_new_delete_misaligned3_supp.vgtest \ + sized_aligned_new_delete_misaligned3_supp.supp \ + sized_aligned_new_delete_misaligned3_supp.stderr.exp \ + sized_aligned_new_delete_misaligned3_supp.stderr.exp_32 \ + new_delete_mismatch_size.stderr.exp \ + new_delete_mismatch_size.vgtest \ + new_delete_mismatch_size_supp.stderr.exp \ + new_delete_mismatch_size_supp.stderr.exp_32 \ + new_delete_mismatch_size_supp.vgtest \ + new_delete_mismatch_size_supp.supp \ deep-backtrace.vgtest deep-backtrace.stderr.exp \ demangle.stderr.exp demangle.vgtest \ big_debuginfo_symbol.stderr.exp big_debuginfo_symbol.vgtest \ @@ -234,6 +264,9 @@ EXTRA_DIST = \ mempool2.stderr.exp mempool2.vgtest \ metadata.stderr.exp metadata.stdout.exp metadata.vgtest \ mismatches.stderr.exp mismatches.vgtest \ + mismatches.stderr.exp2 \ + mismatches_xml.stderr.exp mismatches_xml.vgtest \ + mismatches_xml.stderr.exp2 \ mmaptest.stderr.exp mmaptest.vgtest \ nanoleak_supp.stderr.exp nanoleak_supp.vgtest nanoleak.supp \ nanoleak_dynsupp.stderr.exp nanoleak_dynsupp.vgtest \ @@ -282,6 +315,10 @@ EXTRA_DIST = \ pointer-trace.vgtest \ pointer-trace.stderr.exp \ posix_memalign.stderr.exp posix_memalign.vgtest \ + posix_memalign.stderr.exp-darwin \ + posix_memalign_supp.stderr.exp posix_memalign_supp.vgtest \ + posix_memalign_supp.supp \ + posix_memalign_xml.stderr.exp posix_memalign_xml.vgtest \ post-syscall.stderr.exp post-syscall.vgtest \ reach_thread_register.stderr.exp reach_thread_register.vgtest \ reach_thread_register.stderr.exp-mips32 \ @@ -519,7 +556,9 @@ endif if HAVE_ALIGNED_CXX_ALLOC check_PROGRAMS += cxx17_aligned_new sized_aligned_new_delete_args \ - sized_aligned_new_delete_misaligned + sized_aligned_new_delete_misaligned1 \ + sized_aligned_new_delete_misaligned2 \ + sized_aligned_new_delete_misaligned3 endif if HAVE_PTHREAD_BARRIER @@ -527,7 +566,7 @@ check_PROGRAMS += reach_thread_register endif if HAVE_FSIZED_DEALLOCATION -check_PROGRAMS += sized_delete +check_PROGRAMS += sized_delete new_delete_mismatch_size endif if HAVE_GNU_STPNCPY @@ -583,12 +622,18 @@ cxx17_aligned_new_SOURCES = cxx17_aligned_new.cpp cxx17_aligned_new_CXXFLAGS = -std=c++17 @FLAG_W_NO_MISMATCHED_NEW_DELETE@ sized_aligned_new_delete_args_SOURCES = sized_aligned_new_delete_args.cpp sized_aligned_new_delete_args_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 -sized_aligned_new_delete_misaligned_SOURCES = sized_aligned_new_delete_misaligned.cpp -sized_aligned_new_delete_misaligned_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 +sized_aligned_new_delete_misaligned1_SOURCES = sized_aligned_new_delete_misaligned1.cpp +sized_aligned_new_delete_misaligned1_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 +sized_aligned_new_delete_misaligned2_SOURCES = sized_aligned_new_delete_misaligned2.cpp +sized_aligned_new_delete_misaligned2_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 +sized_aligned_new_delete_misaligned3_SOURCES = sized_aligned_new_delete_misaligned3.cpp +sized_aligned_new_delete_misaligned3_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17 if COMPILER_IS_CLANG cxx17_aligned_new_CXXFLAGS += -fsized-deallocation sized_aligned_new_delete_args_CXXFLAGS += -fsized-deallocation -sized_aligned_new_delete_misaligned_CXXFLAGS += -fsized-deallocation +sized_aligned_new_delete_misaligned1_CXXFLAGS += -fsized-deallocation +sized_aligned_new_delete_misaligned2_CXXFLAGS += -fsized-deallocation +sized_aligned_new_delete_misaligned3_CXXFLAGS += -fsized-deallocation endif endif @@ -637,6 +682,11 @@ memcmptest_CFLAGS = $(AM_CFLAGS) -fno-builtin-memcmp mismatches_SOURCES = mismatches.cpp mismatches_CXXFLAGS = $(AM_CXXFLAGS) @FLAG_W_NO_MISMATCHED_NEW_DELETE@ +if HAVE_FSIZED_DEALLOCATION +new_delete_mismatch_size_SOURCES = new_delete_mismatch_size.cpp +new_delete_mismatch_size_CXXFLAGS = $(AM_CXXFLAGS) @FLAG_FSIZED_DEALLOCATION@ -std=c++17 +endif + new_nothrow_SOURCES = new_nothrow.cpp new_override_SOURCES = new_override.cpp diff --git a/memcheck/tests/duplicate_align_size_errors.cpp b/memcheck/tests/duplicate_align_size_errors.cpp new file mode 100644 index 0000000000..3e0af0d160 --- /dev/null +++ b/memcheck/tests/duplicate_align_size_errors.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include "tests/malloc.h" +#include "../../config.h" + +int main() +{ + std::align_val_t misalign(static_cast(63U)); + std::align_val_t zeroalign(static_cast(0U)); + std::align_val_t onealign(static_cast(1U)); + std::align_val_t align(static_cast(64U)); + std::align_val_t alignx2(static_cast(128U)); + std::size_t size(32); + std::nothrow_t tag; + void *mem = nullptr; + + for (int i = 0 ; i < 2 ; ++i) + { + // Err_BadAlign alignment only + mem = operator new(size, zeroalign, tag); + operator delete(mem, zeroalign, tag); + mem = nullptr; + +#if defined(HAVE_ALIGNED_ALLOC) + // Err_BadAlign size and alignment + mem = aligned_alloc(64U, 100U); + if (mem) + { + free(mem); + mem = nullptr; + } + + // Err.BadSize + mem = aligned_alloc(64U, 0U); + if (mem) + { + free(mem); + mem = nullptr; + } +#endif + + // Err_SizeMismatch + mem = operator new(size, align); + operator delete(mem, size+1, align); + mem = nullptr; + + // Err_AlignMismatch + mem = operator new[](size, align); + operator delete[](mem, size, alignx2); + mem = nullptr; + } +} diff --git a/memcheck/tests/filter_size_t b/memcheck/tests/filter_size_t index 08386b219c..2168a26e2c 100755 --- a/memcheck/tests/filter_size_t +++ b/memcheck/tests/filter_size_t @@ -1,5 +1,7 @@ #! /bin/sh +# change 32 bit size_t (unsigned int) to 64 bit (unsigned long) +# also change 32 bit -1 size_t to 64 bit ./filter_stderr "$@" | -sed "s/unsigned int/unsigned long/" +sed "s/unsigned int/unsigned long/;s/4294967295/18446744073709551615/" diff --git a/memcheck/tests/filter_stanza_and_size_t b/memcheck/tests/filter_stanza_and_size_t new file mode 100755 index 0000000000..fe3691aab0 --- /dev/null +++ b/memcheck/tests/filter_stanza_and_size_t @@ -0,0 +1,6 @@ +#! /bin/sh + + +./filter_stanza "$@" | +sed "s/unsigned int/unsigned long/;s/4294967295/18446744073709551615/" + diff --git a/memcheck/tests/filter_used_supp b/memcheck/tests/filter_used_supp new file mode 100755 index 0000000000..5403ce723a --- /dev/null +++ b/memcheck/tests/filter_used_supp @@ -0,0 +1,7 @@ +#! /bin/sh + +./filter_stderr "$@" | + +grep -v default\.supp | + +grep used_suppression diff --git a/memcheck/tests/filter_xml b/memcheck/tests/filter_xml index e8c0b75cf5..9244706c36 100755 --- a/memcheck/tests/filter_xml +++ b/memcheck/tests/filter_xml @@ -14,6 +14,13 @@ sed "s/.*<\/count>/...<\/count>/" | # Filter out @* version symbol function names sed "s/\(.*\)\@\*<\/fn>/\1<\/fn>/" | sed "s/of size [48].*<\/suppcounts>/...<\/suppcounts>/s" | perl -p -e "s/