Skip to content

Commit

Permalink
Reland "[hwasan] Add definitions for missing operator delete functions"
Browse files Browse the repository at this point in the history
Looks like builders were failing for the sized variants of operator
delete. These are hidden behind the __cpp_sized_deallocation macro
which can be defined with -fsized-deallocation.
  • Loading branch information
PiJoules committed Feb 15, 2023
1 parent a926977 commit 22b7685
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 1 deletion.
16 changes: 16 additions & 0 deletions compiler-rt/lib/hwasan/hwasan_new_delete.cpp
Expand Up @@ -92,6 +92,14 @@ INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
void *ptr, std::nothrow_t const &) {
OPERATOR_DELETE_BODY;
}
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
void *ptr, size_t) NOEXCEPT {
OPERATOR_DELETE_BODY;
}
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
void *ptr, size_t) NOEXCEPT {
OPERATOR_DELETE_BODY;
}

#endif // OPERATOR_NEW_BODY

Expand Down Expand Up @@ -134,5 +142,13 @@ INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
void *ptr, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
OPERATOR_DELETE_BODY;
}
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete(
void *ptr, size_t, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
OPERATOR_DELETE_BODY;
}
INTERCEPTOR_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void operator delete[](
void *ptr, size_t, std::align_val_t, std::nothrow_t const &) NOEXCEPT {
OPERATOR_DELETE_BODY;
}

#endif // OPERATOR_NEW_ALIGN_BODY
115 changes: 114 additions & 1 deletion compiler-rt/test/hwasan/TestCases/new-test.cpp
@@ -1,5 +1,5 @@
// Test basic new functionality.
// RUN: %clangxx_hwasan -std=c++17 %s -o %t
// RUN: %clangxx_hwasan -std=c++17 %s -o %t -fsized-deallocation
// RUN: %run %t

#include <cassert>
Expand All @@ -9,6 +9,100 @@
#include <sanitizer/allocator_interface.h>
#include <sanitizer/hwasan_interface.h>

void operator_new_delete(size_t size) {
void *alloc = operator new(size);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete(alloc);

alloc = operator new(size);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete(alloc, size);
}

void operator_new_delete_array(size_t size) {
void *alloc = operator new[](size);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete[](alloc);

alloc = operator new[](size);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete[](alloc, size);
}

void operator_new_delete(size_t size, std::align_val_t align) {
void *alloc = operator new(size, align);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete(alloc, align);

alloc = operator new(size, align);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete(alloc, size, align);
}

void operator_new_delete_array(size_t size, std::align_val_t align) {
void *alloc = operator new[](size, align);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete[](alloc, align);

alloc = operator new[](size, align);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete[](alloc, size, align);
}

void operator_new_delete(size_t size, const std::nothrow_t &tag) {
void *alloc = operator new(size, tag);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete(alloc, tag);
}

void operator_new_delete_array(size_t size, const std::nothrow_t &tag) {
void *alloc = operator new[](size, tag);
assert(alloc != nullptr);
assert(__sanitizer_get_allocated_size(alloc) == size);
operator delete[](alloc, tag);
}

void operator_new_delete(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
void *alloc = operator new(size, align, tag);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete(alloc, align, tag);
}

void operator_new_delete_array(size_t size, std::align_val_t align, const std::nothrow_t &tag) {
void *alloc = operator new[](size, align, tag);
assert(alloc != nullptr);
assert(reinterpret_cast<uintptr_t>(alloc) % static_cast<uintptr_t>(align) == 0);
assert(__sanitizer_get_allocated_size(alloc) >= size);
operator delete[](alloc, align, tag);
}

void operator_new_delete(size_t size, void *ptr) {
void *alloc = operator new(size, ptr);
assert(alloc == ptr);
operator delete(alloc, ptr);
}

void operator_new_delete_array(size_t size, void *ptr) {
void *alloc = operator new[](size, ptr);
assert(alloc == ptr);
operator delete[](alloc, ptr);
}

int main() {
__hwasan_enable_allocator_tagging();

Expand All @@ -18,6 +112,16 @@ int main() {
assert(__sanitizer_get_allocated_size(a1) == 1);
delete[] a1;

constexpr size_t kSize = 8;
operator_new_delete(kSize);
operator_new_delete_array(kSize);
operator_new_delete(kSize, std::nothrow);
operator_new_delete_array(kSize, std::nothrow);

char buffer[kSize];
operator_new_delete(kSize, buffer);
operator_new_delete_array(kSize, buffer);

#if defined(__cpp_aligned_new) && \
(!defined(__GLIBCXX__) || \
(defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7))
Expand All @@ -28,5 +132,14 @@ int main() {
assert(reinterpret_cast<uintptr_t>(a2) % static_cast<uintptr_t>(kAlign) == 0);
assert(__sanitizer_get_allocated_size(a2) >= 4);
::operator delete(a2, kAlign);

operator_new_delete(kSize, std::align_val_t{kSize});
operator_new_delete_array(kSize, std::align_val_t{kSize});
operator_new_delete(kSize, std::align_val_t{kSize * 2});
operator_new_delete_array(kSize, std::align_val_t{kSize * 2});
operator_new_delete(kSize, std::align_val_t{kSize}, std::nothrow);
operator_new_delete_array(kSize, std::align_val_t{kSize}, std::nothrow);
operator_new_delete(kSize, std::align_val_t{kSize * 2}, std::nothrow);
operator_new_delete_array(kSize, std::align_val_t{kSize * 2}, std::nothrow);
#endif
}

0 comments on commit 22b7685

Please sign in to comment.