Skip to content

asan: refactor new/delete interceptor macros #146696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 2, 2025

Conversation

jcking
Copy link
Contributor

@jcking jcking commented Jul 2, 2025

Refactors new/delete interceptor macros per the discussion in #145087.

@jcking
Copy link
Contributor Author

jcking commented Jul 2, 2025

@vitalybuka

@llvmbot
Copy link
Member

llvmbot commented Jul 2, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Justin King (jcking)

Changes

Refactors new/delete interceptor macros per the discussion in #145087.


Full diff: https://github.com/llvm/llvm-project/pull/146696.diff

1 Files Affected:

  • (modified) compiler-rt/lib/asan/asan_new_delete.cpp (+83-60)
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

Signed-off-by: Justin King <jcking@google.com>
@jcking jcking force-pushed the asan_new_delete_refactor branch from 5d1e29d to b9671a9 Compare July 2, 2025 14:09
@vitalybuka vitalybuka merged commit e3edc1b into llvm:main Jul 2, 2025
7 checks passed
@jcking jcking deleted the asan_new_delete_refactor branch July 2, 2025 18:59
vitalybuka pushed a commit that referenced this pull request Jul 8, 2025
Same as #146696 but for #145357.

---------

Signed-off-by: Justin King <jcking@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants