diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp --- a/compiler-rt/lib/asan/asan_new_delete.cpp +++ b/compiler-rt/lib/asan/asan_new_delete.cpp @@ -94,28 +94,28 @@ // To make sure that C++ allocation/deallocation operators are overridden on // OS X we need to intercept them using their mangled names. #if !SANITIZER_MAC -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size, std::align_val_t align) { OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](size_t size, std::align_val_t align) { OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&) { OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&) { OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/); } @@ -155,40 +155,40 @@ asan_delete(ptr, size, static_cast(align), &stack, type); #if !SANITIZER_MAC -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW_BR); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY(FROM_NEW_BR); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr, size_t size) NOEXCEPT { OPERATOR_DELETE_BODY_SIZE(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr, size_t size) NOEXCEPT { OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr, std::align_val_t align) NOEXCEPT { OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT { OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) { OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&) { OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT { OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW); } -CXX_OPERATOR_ATTRIBUTE +CXX_OPERATOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT { OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR); } diff --git a/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp b/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/replaceable_new_delete.cpp @@ -0,0 +1,28 @@ +// Ensure that operator new/delete are still replaceable. + +// RUN: %clangxx %s -o %t -fsanitize=address -shared-libsan && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx %s -o %t -fsanitize=address -static-libsan && not %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +void *operator new[](size_t size) { + fprintf(stderr, "replaced new\n"); + return malloc(size); +} + +void operator delete[](void *ptr) noexcept { + fprintf(stderr, "replaced delete\n"); + return free(ptr); +} + +int main(int argc, char **argv) { + // CHECK: replaced new + char *x = new char[5]; + // CHECK: replaced delete + delete[] x; + // CHECK: ERROR: AddressSanitizer + *x = 13; + return 0; +}