Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | // // Tests for // T* unsafe_discard_bounds() const; // #include <libkern/c++/bounded_ptr.h> #include <array> #include <cstddef> #include <cstdint> #include <limits> #include <darwintest.h> #include <darwintest_utils.h> #include "test_utils.h" #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) namespace { struct tracking_policy { static bool did_trap; static void trap(char const*) { did_trap = true; } }; bool tracking_policy::did_trap = false; } struct T { int i; }; template <typename T, typename QualT> static void tests() { std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}}; { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ // | | // begin, ptr end test_bounded_ptr<QualT> const ptr(array.begin() + 0, array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[0]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // begin ptr end test_bounded_ptr<QualT> const ptr(array.begin() + 1, array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[1]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // begin ptr end test_bounded_ptr<QualT> const ptr(array.begin() + 2, array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[2]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // begin ptr end test_bounded_ptr<QualT> const ptr(array.begin() + 4, array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[4]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ // | | // begin end,ptr test_bounded_ptr<QualT> const ptr(array.end(), array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == array.end()); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // begin end ptr test_bounded_ptr<QualT> ptr(array.end() - 1, array.begin(), array.end() - 2); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[4]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // begin ptr end test_bounded_ptr<QualT> ptr(array.begin() + 1, array.begin(), array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[1]); } { // T{0} T{1} T{2} T{3} T{4} <one-past-last> // ^ ^ ^ // | | | // ptr begin end test_bounded_ptr<QualT> ptr(array.begin(), array.begin() + 1, array.end()); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == &array[0]); } // Test discarding the bounds of a null pointer { test_bounded_ptr<QualT> const ptr(nullptr, nullptr, nullptr); QualT* raw = ptr.unsafe_discard_bounds(); _assert(raw == nullptr); } // Test discarding the bounds on a pointer outside of representable memory. // Even `unsafe_discard_bounds()` will trap in such conditions. // // To do this, we setup an imaginary object with a very high address, and // we add a large-ish offset to it, such that adding the base to the offset // would fall outside of the representable memory. { tracking_policy::did_trap = false; QualT* end_of_memory = reinterpret_cast<QualT*>(std::numeric_limits<std::uintptr_t>::max()); QualT* base = end_of_memory - 500; // yeah, technically UB std::ptrdiff_t offset = 501; libkern::bounded_ptr<QualT, tracking_policy> ptr(base, base, base + 1); ptr += offset; // now, `base_ + offset_` points outside of representable memory _assert(!tracking_policy::did_trap); (void)ptr.unsafe_discard_bounds(); _assert(tracking_policy::did_trap); } } T_DECL(unsafe_discard_bounds, "bounded_ptr.unsafe_discard_bounds") { tests<T, T>(); tests<T, T const>(); tests<T, T volatile>(); tests<T, T const volatile>(); } |