X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/eb6b6ca394357805f2bdba989abae309f718b4d8..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/tests/safe_allocation_src/operator.subscript.cpp?ds=inline diff --git a/tests/safe_allocation_src/operator.subscript.cpp b/tests/safe_allocation_src/operator.subscript.cpp new file mode 100644 index 000000000..1eb36fb54 --- /dev/null +++ b/tests/safe_allocation_src/operator.subscript.cpp @@ -0,0 +1,84 @@ +// +// Tests for +// T& operator[](std::ptrdiff_t n); +// T const& operator[](std::ptrdiff_t n) const; +// + +#include +#include +#include "test_utils.h" +#include +#include + +struct T { + long i; +}; + +template +static void +tests() +{ + // Test the non-const version + { + RawT* memory = reinterpret_cast(malloc_allocator::allocate(10 * sizeof(RawT))); + for (RawT* ptr = memory; ptr != memory + 10; ++ptr) { + *ptr = RawT{ptr - memory}; // number from 0 to 9 + } + + test_safe_allocation array(memory, 10, libkern::adopt_memory); + for (std::ptrdiff_t n = 0; n != 10; ++n) { + QualT& element = array[n]; + CHECK(&element == memory + n); + } + } + + // Test the const version + { + RawT* memory = reinterpret_cast(malloc_allocator::allocate(10 * sizeof(RawT))); + for (RawT* ptr = memory; ptr != memory + 10; ++ptr) { + *ptr = RawT{ptr - memory}; // number from 0 to 9 + } + + test_safe_allocation const array(memory, 10, libkern::adopt_memory); + for (std::ptrdiff_t n = 0; n != 10; ++n) { + QualT const& element = array[n]; + CHECK(&element == memory + n); + } + } + + // Test with OOB offsets (should trap) + { + using Alloc = libkern::safe_allocation; + RawT* memory = reinterpret_cast(malloc_allocator::allocate(10 * sizeof(RawT))); + Alloc const array(memory, 10, libkern::adopt_memory); + + // Negative offsets + { + tracking_trapping_policy::reset(); + (void)array[-1]; + CHECK(tracking_trapping_policy::did_trap); + } + { + tracking_trapping_policy::reset(); + (void)array[-10]; + CHECK(tracking_trapping_policy::did_trap); + } + + // Too large offsets + { + tracking_trapping_policy::reset(); + (void)array[10]; + CHECK(tracking_trapping_policy::did_trap); + } + { + tracking_trapping_policy::reset(); + (void)array[11]; + CHECK(tracking_trapping_policy::did_trap); + } + } +} + +T_DECL(operator_subscript, "safe_allocation.operator.subscript") { + tests(); + tests(); +}