[compiler-rt] asan: refactor new/delete interceptor macros (PR #146696)
Justin King via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 2 06:52:46 PDT 2025
https://github.com/jcking created https://github.com/llvm/llvm-project/pull/146696
Refactors new/delete interceptor macros per the discussion in #145087.
>From 5d1e29ddb62f8f343750c3dab8f9d1571ca35df3 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 | 143 +++++++++++++----------
1 file changed, 83 insertions(+), 60 deletions(-)
diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp
index 761db0d266fc2..e5dbf037ae48e 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); \
+#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_ALIGN(type, nothrow) \
- GET_STACK_TRACE_MALLOC; \
- void *res = asan_memalign((uptr)align, size, &stack, type); \
- if (!nothrow && UNLIKELY(!res)) \
- ReportOutOfMemory(size, &stack); \
+#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