Skip to content

asan: refactor interceptor allocation/deallocation functions #145087

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jcking
Copy link
Contributor

@jcking jcking commented Jun 20, 2025

Do some refactoring to allocation/deallocation interceptors. Expose explicit per-alloc_type functions and stop accepting explicit AllocType. This ensures we do not accidentally mix.

NOTE: This change rejects attempts to call operator new(<some_size>, static_cast<std::align_val_t>(0)).

For #144435

@llvmbot
Copy link
Member

llvmbot commented Jun 20, 2025

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

Author: Justin King (jcking)

Changes

Do some refactoring to allocation/deallocation interceptors. Expose explicit per-alloc_type functions and stop accepting explicit AllocType. This ensures we do not accidentally mix.

For #144435


Patch is 25.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/145087.diff

7 Files Affected:

  • (modified) compiler-rt/lib/asan/asan_allocator.cpp (+99-12)
  • (modified) compiler-rt/lib/asan/asan_allocator.h (+19-5)
  • (modified) compiler-rt/lib/asan/asan_malloc_linux.cpp (+4-4)
  • (modified) compiler-rt/lib/asan/asan_malloc_mac.cpp (+3-3)
  • (modified) compiler-rt/lib/asan/asan_malloc_win.cpp (+5-5)
  • (modified) compiler-rt/lib/asan/asan_new_delete.cpp (+106-76)
  • (modified) compiler-rt/lib/asan/tests/asan_noinst_test.cpp (+8-10)
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index 3a55c2af65653..7b2841f9bde00 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -997,17 +997,12 @@ void PrintInternalAllocatorStats() {
   instance.PrintStats();
 }
 
-void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) {
-  instance.Deallocate(ptr, 0, 0, stack, alloc_type);
-}
-
-void asan_delete(void *ptr, uptr size, uptr alignment,
-                 BufferedStackTrace *stack, AllocType alloc_type) {
-  instance.Deallocate(ptr, size, alignment, stack, alloc_type);
+void asan_free(void *ptr, BufferedStackTrace *stack) {
+  instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC);
 }
 
 void *asan_malloc(uptr size, BufferedStackTrace *stack) {
-  return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
+  return SetErrnoOnNull(instance.Allocate(size, 0, stack, FROM_MALLOC, true));
 }
 
 void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
@@ -1027,7 +1022,7 @@ void *asan_reallocarray(void *p, uptr nmemb, uptr size,
 
 void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
   if (!p)
-    return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
+    return SetErrnoOnNull(instance.Allocate(size, 0, stack, FROM_MALLOC, true));
   if (size == 0) {
     if (flags()->allocator_frees_and_returns_null_on_realloc_zero) {
       instance.Deallocate(p, 0, 0, stack, FROM_MALLOC);
@@ -1058,8 +1053,7 @@ void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
       instance.Allocate(size, PageSize, stack, FROM_MALLOC, true));
 }
 
-void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
-                    AllocType alloc_type) {
+void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack) {
   if (UNLIKELY(!IsPowerOfTwo(alignment))) {
     errno = errno_EINVAL;
     if (AllocatorMayReturnNull())
@@ -1067,7 +1061,7 @@ void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
     ReportInvalidAllocationAlignment(alignment, stack);
   }
   return SetErrnoOnNull(
-      instance.Allocate(size, alignment, stack, alloc_type, true));
+      instance.Allocate(size, alignment, stack, FROM_MALLOC, true));
 }
 
 void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack) {
@@ -1107,6 +1101,99 @@ uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp) {
   return usable_size;
 }
 
+namespace {
+
+void *asan_new(uptr size, BufferedStackTrace *stack, bool array) {
+  return SetErrnoOnNull(
+      instance.Allocate(size, 0, stack, array ? FROM_NEW_BR : FROM_NEW, true));
+}
+
+void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack,
+                       bool array) {
+  if (UNLIKELY(!IsPowerOfTwo(alignment))) {
+    errno = errno_EINVAL;
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    ReportInvalidAllocationAlignment(alignment, stack);
+  }
+  return SetErrnoOnNull(instance.Allocate(
+      size, alignment, stack, array ? FROM_NEW_BR : FROM_NEW, true));
+}
+
+void asan_delete(void *ptr, BufferedStackTrace *stack, bool array) {
+  instance.Deallocate(ptr, 0, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
+}
+
+void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack,
+                         bool array) {
+  instance.Deallocate(ptr, 0, alignment, stack, array ? FROM_NEW_BR : FROM_NEW);
+}
+
+void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack,
+                       bool array) {
+  instance.Deallocate(ptr, size, 0, stack, array ? FROM_NEW_BR : FROM_NEW);
+}
+
+void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
+                               BufferedStackTrace *stack, bool array) {
+  instance.Deallocate(ptr, size, alignment, stack,
+                      array ? FROM_NEW_BR : FROM_NEW);
+}
+
+}  // namespace
+
+void *asan_new(uptr size, BufferedStackTrace *stack) {
+  return asan_new(size, stack, /*array=*/false);
+}
+
+void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack) {
+  return asan_new_aligned(size, alignment, stack, /*array=*/false);
+}
+
+void *asan_new_array(uptr size, BufferedStackTrace *stack) {
+  return asan_new(size, stack, /*array=*/true);
+}
+
+void *asan_new_array_aligned(uptr size, uptr alignment,
+                             BufferedStackTrace *stack) {
+  return asan_new_aligned(size, alignment, stack, /*array=*/true);
+}
+
+void asan_delete(void *ptr, BufferedStackTrace *stack) {
+  asan_delete(ptr, stack, /*array=*/false);
+}
+
+void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack) {
+  asan_delete_aligned(ptr, alignment, stack, /*array=*/false);
+}
+
+void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack) {
+  asan_delete_sized(ptr, size, stack, /*array=*/false);
+}
+
+void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
+                               BufferedStackTrace *stack) {
+  asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/false);
+}
+
+void asan_delete_array(void *ptr, BufferedStackTrace *stack) {
+  asan_delete(ptr, stack, /*array=*/true);
+}
+
+void asan_delete_array_aligned(void *ptr, uptr alignment,
+                               BufferedStackTrace *stack) {
+  asan_delete_aligned(ptr, alignment, stack, /*array=*/true);
+}
+
+void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack) {
+  asan_delete_sized(ptr, size, stack, /*array=*/true);
+}
+
+void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
+                                     BufferedStackTrace *stack) {
+  asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/true);
+}
+
 uptr asan_mz_size(const void *ptr) {
   return instance.AllocationSize(reinterpret_cast<uptr>(ptr));
 }
diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index db8dc3bebfc62..1ec56f23663f2 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -269,11 +269,8 @@ struct AsanThreadLocalMallocStorage {
   AsanThreadLocalMallocStorage() {}
 };
 
-void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
-                    AllocType alloc_type);
-void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);
-void asan_delete(void *ptr, uptr size, uptr alignment,
-                 BufferedStackTrace *stack, AllocType alloc_type);
+void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack);
+void asan_free(void *ptr, BufferedStackTrace *stack);
 
 void *asan_malloc(uptr size, BufferedStackTrace *stack);
 void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
@@ -288,6 +285,23 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
                         BufferedStackTrace *stack);
 uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp);
 
+void *asan_new(uptr size, BufferedStackTrace *stack);
+void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack);
+void *asan_new_array(uptr size, BufferedStackTrace *stack);
+void *asan_new_array_aligned(uptr size, uptr alignment,
+                             BufferedStackTrace *stack);
+void asan_delete(void *ptr, BufferedStackTrace *stack);
+void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack);
+void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack);
+void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment,
+                               BufferedStackTrace *stack);
+void asan_delete_array(void *ptr, BufferedStackTrace *stack);
+void asan_delete_array_aligned(void *ptr, uptr alignment,
+                               BufferedStackTrace *stack);
+void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack);
+void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment,
+                                     BufferedStackTrace *stack);
+
 uptr asan_mz_size(const void *ptr);
 void asan_mz_force_lock();
 void asan_mz_force_unlock();
diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp
index 3f023d4c2ed0a..add57318785be 100644
--- a/compiler-rt/lib/asan/asan_malloc_linux.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp
@@ -49,7 +49,7 @@ INTERCEPTOR(void, free, void *ptr) {
   if (DlsymAlloc::PointerIsMine(ptr))
     return DlsymAlloc::Free(ptr);
   GET_STACK_TRACE_FREE;
-  asan_free(ptr, &stack, FROM_MALLOC);
+  asan_free(ptr, &stack);
 }
 
 #if SANITIZER_INTERCEPT_CFREE
@@ -57,7 +57,7 @@ INTERCEPTOR(void, cfree, void *ptr) {
   if (DlsymAlloc::PointerIsMine(ptr))
     return DlsymAlloc::Free(ptr);
   GET_STACK_TRACE_FREE;
-  asan_free(ptr, &stack, FROM_MALLOC);
+  asan_free(ptr, &stack);
 }
 #endif // SANITIZER_INTERCEPT_CFREE
 
@@ -93,12 +93,12 @@ INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
 #if SANITIZER_INTERCEPT_MEMALIGN
 INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
   GET_STACK_TRACE_MALLOC;
-  return asan_memalign(boundary, size, &stack, FROM_MALLOC);
+  return asan_memalign(boundary, size, &stack);
 }
 
 INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
   GET_STACK_TRACE_MALLOC;
-  return asan_memalign(boundary, size, &stack, FROM_MALLOC);
+  return asan_memalign(boundary, size, &stack);
 }
 #endif // SANITIZER_INTERCEPT_MEMALIGN
 
diff --git a/compiler-rt/lib/asan/asan_malloc_mac.cpp b/compiler-rt/lib/asan/asan_malloc_mac.cpp
index f25d7e1901536..a442bdbbaa4d3 100644
--- a/compiler-rt/lib/asan/asan_malloc_mac.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_mac.cpp
@@ -31,7 +31,7 @@ using namespace __asan;
 #  define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock()
 #  define COMMON_MALLOC_MEMALIGN(alignment, size) \
     GET_STACK_TRACE_MALLOC;                       \
-    void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC)
+    void *p = asan_memalign(alignment, size, &stack)
 #  define COMMON_MALLOC_MALLOC(size) \
     GET_STACK_TRACE_MALLOC;          \
     void *p = asan_malloc(size, &stack)
@@ -46,10 +46,10 @@ using namespace __asan;
     int res = asan_posix_memalign(memptr, alignment, size, &stack);
 #  define COMMON_MALLOC_VALLOC(size) \
     GET_STACK_TRACE_MALLOC;          \
-    void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
+    void *p = asan_memalign(GetPageSizeCached(), size, &stack);
 #  define COMMON_MALLOC_FREE(ptr) \
     GET_STACK_TRACE_FREE;         \
-    asan_free(ptr, &stack, FROM_MALLOC);
+    asan_free(ptr, &stack);
 #  define COMMON_MALLOC_SIZE(ptr) uptr size = asan_mz_size(ptr);
 #  define COMMON_MALLOC_FILL_STATS(zone, stats)                    \
     AsanMallocStats malloc_stats;                                  \
diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp
index 3278f07219876..8d98da940800f 100644
--- a/compiler-rt/lib/asan/asan_malloc_win.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_win.cpp
@@ -69,7 +69,7 @@ __declspec(noinline) size_t _msize_base(void *ptr) { return _msize(ptr); }
 
 __declspec(noinline) void free(void *ptr) {
   GET_STACK_TRACE_FREE;
-  return asan_free(ptr, &stack, FROM_MALLOC);
+  return asan_free(ptr, &stack);
 }
 
 __declspec(noinline) void _free_dbg(void *ptr, int) { free(ptr); }
@@ -252,7 +252,7 @@ INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
     CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags");
   }
   GET_STACK_TRACE_FREE;
-  asan_free(lpMem, &stack, FROM_MALLOC);
+  asan_free(lpMem, &stack);
   return true;
 }
 
@@ -306,7 +306,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
         if (replacement_alloc) {
           size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem);
           if (old_size == ((size_t)0) - 1) {
-            asan_free(replacement_alloc, &stack, FROM_MALLOC);
+            asan_free(replacement_alloc, &stack);
             return nullptr;
           }
           REAL(memcpy)(replacement_alloc, lpMem, old_size);
@@ -331,7 +331,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
         old_usable_size = asan_malloc_usable_size(lpMem, pc, bp);
         REAL(memcpy)(replacement_alloc, lpMem,
                      Min<size_t>(dwBytes, old_usable_size));
-        asan_free(lpMem, &stack, FROM_MALLOC);
+        asan_free(lpMem, &stack);
       }
       return replacement_alloc;
     }
@@ -429,7 +429,7 @@ INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags,
     return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress);
   }
   GET_STACK_TRACE_FREE;
-  asan_free(BaseAddress, &stack, FROM_MALLOC);
+  asan_free(BaseAddress, &stack);
   return true;
 }
 
diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp
index b5b1ced8ac5ed..b5d0447f809d2 100644
--- a/compiler-rt/lib/asan/asan_new_delete.cpp
+++ b/compiler-rt/lib/asan/asan_new_delete.cpp
@@ -60,17 +60,19 @@ 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(array, nothrow)                                    \
+  GET_STACK_TRACE_MALLOC;                                                    \
+  void *res = array ? asan_new_array(size, &stack) : asan_new(size, &stack); \
+  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);                          \
+#define OPERATOR_NEW_BODY_ALIGN(array, nothrow)                              \
+  GET_STACK_TRACE_MALLOC;                                                    \
+  void *res =                                                                \
+      array ? asan_new_array_aligned(size, static_cast<uptr>(align), &stack) \
+            : asan_new_aligned(size, static_cast<uptr>(align), &stack);      \
+  if (!nothrow && UNLIKELY(!res))                                            \
+    ReportOutOfMemory(size, &stack);                                         \
   return res;
 
 // On OS X it's not enough to just provide our own 'operator new' and
@@ -82,106 +84,134 @@ 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(false /*array*/, false /*nothrow*/);
+}
 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(true /*array*/, false /*nothrow*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/); }
+void *operator new(size_t size, std::nothrow_t const &) {
+  OPERATOR_NEW_BODY(false /*array*/, true /*nothrow*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); }
+void *operator new[](size_t size, std::nothrow_t const &) {
+  OPERATOR_NEW_BODY(true /*array*/, true /*nothrow*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/); }
+void *operator new(size_t size, std::align_val_t align) {
+  OPERATOR_NEW_BODY_ALIGN(false /*array*/, false /*nothrow*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/); }
+void *operator new[](size_t size, std::align_val_t align) {
+  OPERATOR_NEW_BODY_ALIGN(true /*array*/, false /*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, true /*nothrow*/); }
+void *operator new(size_t size, std::align_val_t align,
+                   std::nothrow_t const &) {
+  OPERATOR_NEW_BODY_ALIGN(false /*array*/, true /*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*/); }
-
+void *operator new[](size_t size, std::align_val_t align,
+                     std::nothrow_t const &) {
+  OPERATOR_NEW_BODY_ALIGN(true /*array*/, true /*nothrow*/);
+}
 #else  // SANITIZER_APPLE
 INTERCEPTOR(void *, _Znwm, size_t size) {
-  OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
+  OPERATOR_NEW_BODY(false /*array*/, false /*nothrow*/);
 }
 INTERCEPTOR(void *, _Znam, size_t size) {
-  OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
+  OPERATOR_NEW_BODY(true /*array*/, false /*nothrow*/);
 }
 INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
+  OPERATOR_NEW_BODY(false /*array*/, true /*nothrow*/);
 }
 INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
-  OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
+  OPERATOR_NEW_BODY(true /*array*/, true /*nothrow*/);
 }
 #endif  // !SANITIZER_APPLE
 
-#define OPERATOR_DELETE_BODY(type) \
-  GET_STACK_TRACE_FREE;            \
-  asan_delete(ptr, 0, 0, &stack, type);
+#define OPERATOR_DELETE_BODY(array) \
+  GET_STACK_TRACE_FREE;             \
+  array ? asan_delete_array(ptr, &stack) : asan_delete(ptr, &stack);
 
-#define OPERATOR_DELETE_BODY_SIZE(type) \
-  GET_STACK_TRACE_FREE;                 \
-  asan_delete(ptr, size, 0, &stack, type);
+#define OPERATOR_DELETE_BODY_SIZE(array)             \
+  GET_STACK_TRACE_FREE;                              \
+  array ? asan_delete_array_sized(ptr, size, &stack) \
+        : asan_delete_sized(ptr, size, &stack);
 
-#define OPERATOR_DELETE_BODY_ALIGN(type) \
-  GET_STACK_TRACE_FREE;                  \
-  asan_delete(ptr, 0, static_cast<uptr>(align), &stack, type);
+#define OPERATOR_DELETE_BODY_ALIGN(array)                                  \
+  GET_STACK_TRACE_FREE;                                                    \
+  array ? asan_delete_array_aligned(ptr, static_cast<uptr>(align), &stack) \
+        : asan_delete_aligned(ptr, static_cast<uptr>(align), &stack);
 
-#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \
-  GET_STACK_TRACE_FREE;                       \
-  asan_delete(ptr, size, static_cast<uptr>(align), &stack, type);
+#define OPERATOR_DELETE_BODY_SIZE_ALIGN(array)                                 \
+  GET_STACK_TRACE_FREE;                                                        \
+  array ? asan_delete_array_sized_aligned(ptr, size, static_cast<uptr>(align), \
+                                          &stack)                              \
+        : asan_delete_sized_aligned(ptr, size, static_cast<uptr>(align),       \
+                                    &stack);
 
 #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(false /*array*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr) NOEXCEPT
-{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
+void operator delete[](void *ptr) NOEXCEPT {
+  OPERATOR_DELETE_BODY(true /*array*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW); }
+void operator delete(void *ptr, std::nothrow_t const &) {
+  OPERATOR_DELETE_BODY(false /*array*/);
+}
 CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW_...
[truncated]

@vitalybuka vitalybuka self-requested a review June 30, 2025 18:58
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
vitalybuka pushed a commit that referenced this pull request Jul 2, 2025
Refactors new/delete interceptor macros per the discussion in #145087.

Signed-off-by: Justin King <jcking@google.com>
@jcking jcking force-pushed the asan_free_aligned_sized branch from eae5608 to 49eb25f Compare July 2, 2025 19:06
@wrotki
Copy link
Contributor

wrotki commented Jul 2, 2025

Looks reasonable - however, is it dependent (stacked) on #146696 change?

@jcking
Copy link
Contributor Author

jcking commented Jul 3, 2025

Looks reasonable - however, is it dependent (stacked) on #146696 change?

Yep. I split that part out, as requested by @vitalybuka.

@wrotki
Copy link
Contributor

wrotki commented Jul 3, 2025

Tried to build/test your change on Mac (xcrun ninja check-compiler-rt) and see these failures:

  AddressSanitizer-arm64-darwin :: TestCases/Posix/new_array_cookie_test.cpp
  AddressSanitizer-arm64-darwin :: TestCases/Posix/new_array_cookie_uaf_test.cpp
  AddressSanitizer-arm64-darwin :: TestCases/strcpy-overlap.cpp
  AddressSanitizer-arm64-darwin :: TestCases/strncpy-overlap.cpp

Not sure if your change affect those, but feels to touch the area which is close - can you run this test (it's Posix so possible problems should also show up on Linux)? NM if you've already did.

@jcking
Copy link
Contributor Author

jcking commented Jul 7, 2025

Tried to build/test your change on Mac (xcrun ninja check-compiler-rt) and see these failures:

  AddressSanitizer-arm64-darwin :: TestCases/Posix/new_array_cookie_test.cpp
  AddressSanitizer-arm64-darwin :: TestCases/Posix/new_array_cookie_uaf_test.cpp
  AddressSanitizer-arm64-darwin :: TestCases/strcpy-overlap.cpp
  AddressSanitizer-arm64-darwin :: TestCases/strncpy-overlap.cpp

Not sure if your change affect those, but feels to touch the area which is close - can you run this test (it's Posix so possible problems should also show up on Linux)? NM if you've already did.

For me TestCases/Linux/aligned_delete_test.cpp fails on Linux. Investigating.

@jcking jcking force-pushed the asan_free_aligned_sized branch from 49eb25f to c28c08e Compare July 7, 2025 14:48
Signed-off-by: Justin King <jcking@google.com>
@jcking jcking force-pushed the asan_free_aligned_sized branch from c28c08e to 68c6640 Compare July 7, 2025 14:51
@jcking
Copy link
Contributor Author

jcking commented Jul 7, 2025

Oh, it would help if I didn't switch up the align and size function parameters. Fixed and retesting.

@jcking
Copy link
Contributor Author

jcking commented Jul 7, 2025

Passes now. Feel free to retest on macos.

Copy link
Contributor

@davidmrdavid davidmrdavid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just an open source contributor without approval rights, but left some nits. Feel free to dismiss!

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.

6 participants