[compiler-rt] asan: refactor new/delete interceptor macros (PR #146696)
Justin King via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 07:09:13 PDT 2025
https://github.com/jcking updated https://github.com/llvm/llvm-project/pull/146696
>From b9671a9e6ebabc5c8d9280f460a617dcce639e58 Mon Sep 17 00:00:00 2001
From: Justin King <jcking at google.com>
Date: Wed, 2 Jul 2025 06:51:07 -0700
Subject: [PATCH] asan: refactor new/delete interceptor macros
Signed-off-by: Justin King <jcking at google.com>
---
compiler-rt/lib/asan/asan_new_delete.cpp | 147 +++++++++++++----------
1 file changed, 85 insertions(+), 62 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp
index 761db0d266fc2..99c7c9938dfb3 100644
--- a/compiler-rt/lib/asan/asan_new_delete.cpp
+++ b/compiler-rt/lib/asan/asan_new_delete.cpp
@@ -60,18 +60,42 @@ enum class align_val_t: size_t {};
// TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM.
// For local pool allocation, align to SHADOW_GRANULARITY to match asan
// allocator behavior.
-#define OPERATOR_NEW_BODY(type, nothrow) \
- GET_STACK_TRACE_MALLOC; \
- void *res = asan_memalign(0, size, &stack, type); \
- if (!nothrow && UNLIKELY(!res)) \
- ReportOutOfMemory(size, &stack); \
- return res;
-#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
- GET_STACK_TRACE_MALLOC; \
- void *res = asan_memalign((uptr)align, size, &stack, type); \
- if (!nothrow && UNLIKELY(!res)) \
- ReportOutOfMemory(size, &stack); \
- return res;
+#define OPERATOR_NEW_BODY \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign(0, size, &stack, FROM_NEW); \
+ if (UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
+ return res
+#define OPERATOR_NEW_BODY_NOTHROW \
+ GET_STACK_TRACE_MALLOC; \
+ return asan_memalign(0, size, &stack, FROM_NEW)
+#define OPERATOR_NEW_BODY_ARRAY \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign(0, size, &stack, FROM_NEW_BR); \
+ if (UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
+ return res
+#define OPERATOR_NEW_BODY_ARRAY_NOTHROW \
+ GET_STACK_TRACE_MALLOC; \
+ return asan_memalign(0, size, &stack, FROM_NEW_BR)
+#define OPERATOR_NEW_BODY_ALIGN \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign((uptr)align, size, &stack, FROM_NEW); \
+ if (UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
+ return res
+#define OPERATOR_NEW_BODY_ALIGN_NOTHROW \
+ GET_STACK_TRACE_MALLOC; \
+ return asan_memalign((uptr)align, size, &stack, FROM_NEW)
+#define OPERATOR_NEW_BODY_ALIGN_ARRAY \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign((uptr)align, size, &stack, FROM_NEW_BR); \
+ if (UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
+ return res
+#define OPERATOR_NEW_BODY_ALIGN_ARRAY_NOTHROW \
+ GET_STACK_TRACE_MALLOC; \
+ return asan_memalign((uptr)align, size, &stack, FROM_NEW_BR)
// On OS X it's not enough to just provide our own 'operator new' and
// 'operator delete' implementations, because they're going to be in the
@@ -82,129 +106,128 @@ enum class align_val_t: size_t {};
// OS X we need to intercept them using their mangled names.
#if !SANITIZER_APPLE
CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
-}
+void *operator new(size_t size) { OPERATOR_NEW_BODY; }
CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
-}
+void *operator new[](size_t size) { OPERATOR_NEW_BODY_ARRAY; }
CXX_OPERATOR_ATTRIBUTE
void *operator new(size_t size, std::nothrow_t const &) {
- OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
+ OPERATOR_NEW_BODY_NOTHROW;
}
CXX_OPERATOR_ATTRIBUTE
void *operator new[](size_t size, std::nothrow_t const &) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
+ OPERATOR_NEW_BODY_ARRAY_NOTHROW;
}
CXX_OPERATOR_ATTRIBUTE
void *operator new(size_t size, std::align_val_t align) {
- OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/);
+ OPERATOR_NEW_BODY_ALIGN;
}
CXX_OPERATOR_ATTRIBUTE
void *operator new[](size_t size, std::align_val_t align) {
- OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/);
+ OPERATOR_NEW_BODY_ALIGN_ARRAY;
}
CXX_OPERATOR_ATTRIBUTE
void *operator new(size_t size, std::align_val_t align,
std::nothrow_t const &) {
- OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/);
+ OPERATOR_NEW_BODY_ALIGN_NOTHROW;
}
CXX_OPERATOR_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*/);
+ OPERATOR_NEW_BODY_ALIGN_ARRAY_NOTHROW;
}
#else // SANITIZER_APPLE
-INTERCEPTOR(void *, _Znwm, size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
-}
-INTERCEPTOR(void *, _Znam, size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
-}
+INTERCEPTOR(void *, _Znwm, size_t size) { OPERATOR_NEW_BODY; }
+INTERCEPTOR(void *, _Znam, size_t size) { OPERATOR_NEW_BODY_ARRAY; }
INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
- OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
+ OPERATOR_NEW_BODY_NOTHROW;
}
INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
+ OPERATOR_NEW_BODY_ARRAY_NOTHROW;
}
#endif // !SANITIZER_APPLE
-#define OPERATOR_DELETE_BODY(type) \
+#define OPERATOR_DELETE_BODY \
+ GET_STACK_TRACE_FREE; \
+ asan_delete(ptr, 0, 0, &stack, FROM_NEW)
+#define OPERATOR_DELETE_BODY_ARRAY \
GET_STACK_TRACE_FREE; \
- asan_delete(ptr, 0, 0, &stack, type);
-
-#define OPERATOR_DELETE_BODY_SIZE(type) \
- GET_STACK_TRACE_FREE; \
- asan_delete(ptr, size, 0, &stack, type);
-
-#define OPERATOR_DELETE_BODY_ALIGN(type) \
+ asan_delete(ptr, 0, 0, &stack, FROM_NEW_BR)
+#define OPERATOR_DELETE_BODY_ALIGN \
+ GET_STACK_TRACE_FREE; \
+ asan_delete(ptr, 0, static_cast<uptr>(align), &stack, FROM_NEW)
+#define OPERATOR_DELETE_BODY_ALIGN_ARRAY \
GET_STACK_TRACE_FREE; \
- asan_delete(ptr, 0, static_cast<uptr>(align), &stack, type);
-
-#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \
+ asan_delete(ptr, 0, static_cast<uptr>(align), &stack, FROM_NEW_BR)
+#define OPERATOR_DELETE_BODY_SIZE \
+ GET_STACK_TRACE_FREE; \
+ asan_delete(ptr, size, 0, &stack, FROM_NEW)
+#define OPERATOR_DELETE_BODY_SIZE_ARRAY \
+ GET_STACK_TRACE_FREE; \
+ asan_delete(ptr, size, 0, &stack, FROM_NEW_BR)
+#define OPERATOR_DELETE_BODY_SIZE_ALIGN \
+ GET_STACK_TRACE_FREE; \
+ asan_delete(ptr, size, static_cast<uptr>(align), &stack, FROM_NEW)
+#define OPERATOR_DELETE_BODY_SIZE_ALIGN_ARRAY \
GET_STACK_TRACE_FREE; \
- asan_delete(ptr, size, static_cast<uptr>(align), &stack, type);
+ asan_delete(ptr, size, static_cast<uptr>(align), &stack, FROM_NEW_BR)
#if !SANITIZER_APPLE
CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY(FROM_NEW); }
+void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr) NOEXCEPT {
- OPERATOR_DELETE_BODY(FROM_NEW_BR);
-}
+void operator delete[](void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY_ARRAY; }
CXX_OPERATOR_ATTRIBUTE
void operator delete(void *ptr, std::nothrow_t const &) {
- OPERATOR_DELETE_BODY(FROM_NEW);
+ OPERATOR_DELETE_BODY;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete[](void *ptr, std::nothrow_t const &) {
- OPERATOR_DELETE_BODY(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_ARRAY;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete(void *ptr, size_t size) NOEXCEPT {
- OPERATOR_DELETE_BODY_SIZE(FROM_NEW);
+ OPERATOR_DELETE_BODY_SIZE;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete[](void *ptr, size_t size) NOEXCEPT {
- OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_SIZE_ARRAY;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete(void *ptr, std::align_val_t align) NOEXCEPT {
- OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);
+ OPERATOR_DELETE_BODY_ALIGN;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT {
- OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_ALIGN_ARRAY;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete(void *ptr, std::align_val_t align,
std::nothrow_t const &) {
- OPERATOR_DELETE_BODY_ALIGN(FROM_NEW);
+ OPERATOR_DELETE_BODY_ALIGN;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete[](void *ptr, std::align_val_t align,
std::nothrow_t const &) {
- OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_ALIGN_ARRAY;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT {
- OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW);
+ OPERATOR_DELETE_BODY_SIZE_ALIGN;
}
CXX_OPERATOR_ATTRIBUTE
void operator delete[](void *ptr, size_t size,
std::align_val_t align) NOEXCEPT {
- OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_SIZE_ALIGN_ARRAY;
}
#else // SANITIZER_APPLE
-INTERCEPTOR(void, _ZdlPv, void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); }
-INTERCEPTOR(void, _ZdaPv, void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW_BR); }
+INTERCEPTOR(void, _ZdlPv, void *ptr) { OPERATOR_DELETE_BODY; }
+INTERCEPTOR(void, _ZdaPv, void *ptr) { OPERATOR_DELETE_BODY_ARRAY; }
INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const &) {
- OPERATOR_DELETE_BODY(FROM_NEW);
+ OPERATOR_DELETE_BODY;
}
INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const &) {
- OPERATOR_DELETE_BODY(FROM_NEW_BR);
+ OPERATOR_DELETE_BODY_ARRAY;
}
#endif // !SANITIZER_APPLE
More information about the llvm-commits
mailing list