/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/sigaltstack
/memcheck/tests/sigkill
/memcheck/tests/signal2
TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \
\
+ if ((alignment == 0) \
+ || ((alignment & (alignment - 1)) != 0)) { \
+ return 0; \
+ } \
+ \
/* 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_##vg_replacement, n, alignment ); \
MALLOC_TRACE(" = %p\n", v ); \
if (!v) SET_ERRNO_ENOMEM; \
TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(n); \
MALLOC_TRACE(#fnname "(size %llu, al %llu)", (ULong)n, (ULong)alignment ); \
\
+ if ((alignment == 0) \
+ || ((alignment & (alignment - 1)) != 0)) { \
+ VALGRIND_PRINTF( \
+ "new/new[] aligned failed and should throw an exception, but Valgrind\n"); \
+ VALGRIND_PRINTF_BACKTRACE( \
+ " cannot throw exceptions and so is aborting instead. Sorry.\n"); \
+ my_exit(1); \
+ } \
+ \
/* 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_##vg_replacement, n, alignment ); \
MALLOC_TRACE(" = %p\n", v ); \
if (NULL == v) { \
sized_aligned_new_delete_args.stderr.exp \
sized_aligned_new_delete_args.vgtest \
sized_aligned_new_delete_args.stderr.exp_32 \
+ sized_aligned_new_delete_misaligned.stderr.exp \
+ sized_aligned_new_delete_misaligned.vgtest \
deep-backtrace.vgtest deep-backtrace.stderr.exp \
demangle.stderr.exp demangle.vgtest \
big_debuginfo_symbol.stderr.exp big_debuginfo_symbol.vgtest \
endif
if HAVE_ALIGNED_CXX_ALLOC
-check_PROGRAMS += cxx17_aligned_new sized_aligned_new_delete_args
+check_PROGRAMS += cxx17_aligned_new sized_aligned_new_delete_args \
+ sized_aligned_new_delete_misaligned
endif
if HAVE_PTHREAD_BARRIER
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
endif
demangle_SOURCES = demangle.cpp
--- /dev/null
+#include <cstdlib>
+#include <new>
+#include <iostream>
+#include <cassert>
+#include <cstdio>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "valgrind.h"
+
+int main() {
+ std::align_val_t misalign(static_cast<std::align_val_t>(63U));
+ std::align_val_t zeroalign(static_cast<std::align_val_t>(0U));
+ std::align_val_t onealign(static_cast<std::align_val_t>(1U));
+ std::align_val_t align(static_cast<std::align_val_t>(64U));
+ size_t size(32);
+ std::nothrow_t tag;
+ void *mem = nullptr;
+
+ // libc++ will allocate something for size zero
+ // but libstdc++ doesn't
+ mem = operator new(size, zeroalign, tag);
+ if (RUNNING_ON_VALGRIND) {
+ assert(!mem);
+ }
+ operator delete(mem, zeroalign, tag);
+ mem = nullptr;
+
+ mem = operator new(size, onealign, tag);
+ assert(mem);
+ operator delete(mem, onealign, tag);
+ mem = nullptr;
+
+ mem = operator new(size, align);
+ operator delete(mem, misalign);
+ mem = nullptr;
+
+ mem = operator new[](size, align);
+ operator delete[](mem, misalign);
+ mem = nullptr;
+
+ // doesn't matter that tag is uninit
+ // don't want to see an error
+ mem = operator new(size, misalign, tag);
+ operator delete(mem, misalign, tag);
+ assert(!mem);
+
+ mem = operator new[](size, misalign, tag);
+ operator delete[](mem, misalign, tag);
+ assert(!mem);
+
+ mem = operator new(size, align);
+ operator delete(mem, size, misalign);
+ mem = nullptr;
+
+ mem = operator new[](size, align);
+ operator delete[](mem, size, misalign);
+
+ // the last two throw exceptions in C++
+ int pid;
+ int status;
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
+ if (pid == 0) {
+ // child
+ mem = operator new(size, misalign);
+ // should throw
+ assert(false);
+ }
+ waitpid(pid, &status, 0);
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
+ if (pid == 0) {
+ // child
+ mem = operator new[](size, misalign);
+ // should throw
+ assert(false);
+ }
+ waitpid(pid, &status, 0);
+}
--- /dev/null
+new/new[] aligned failed and should throw an exception, but Valgrind
+ cannot throw exceptions and so is aborting instead. Sorry.
+ ...
+ by 0x........: operator new(unsigned long, std::align_val_t) (vg_replace_malloc.c:...)
+ by 0x........: main (sized_aligned_new_delete_misaligned.cpp:69)
+new/new[] aligned failed and should throw an exception, but Valgrind
+ cannot throw exceptions and so is aborting instead. Sorry.
+ ...
+ by 0x........: operator new[](unsigned long, std::align_val_t) (vg_replace_malloc.c:...)
+ by 0x........: main (sized_aligned_new_delete_misaligned.cpp:81)
--- /dev/null
+prog: sized_aligned_new_delete_misaligned
+prereq: test -e ./sized_aligned_new_delete_misaligned
+vgopts: -q