]>
git.saurik.com Git - apple/xnu.git/blob - tests/bounded_ptr_src/unsafe_discard_bounds.cpp
   3 //  T* unsafe_discard_bounds() const; 
   6 #include <libkern/c++/bounded_ptr.h> 
  11 #include <darwintest.h> 
  12 #include <darwintest_utils.h> 
  13 #include "test_utils.h" 
  15 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) 
  18 struct tracking_policy 
{ 
  26 bool tracking_policy::did_trap 
= false; 
  31 template <typename T
, typename QualT
> 
  35         std::array
<T
, 5> array 
= {T
{0}, T
{1}, T
{2}, T
{3}, T
{4}}; 
  38                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  42                 test_bounded_ptr
<QualT
> const ptr(array
.begin() + 0, array
.begin(), array
.end()); 
  43                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  44                 _assert(raw 
== &array
[0]); 
  47                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  51                 test_bounded_ptr
<QualT
> const ptr(array
.begin() + 1, array
.begin(), array
.end()); 
  52                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  53                 _assert(raw 
== &array
[1]); 
  56                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  60                 test_bounded_ptr
<QualT
> const ptr(array
.begin() + 2, array
.begin(), array
.end()); 
  61                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  62                 _assert(raw 
== &array
[2]); 
  65                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  69                 test_bounded_ptr
<QualT
> const ptr(array
.begin() + 4, array
.begin(), array
.end()); 
  70                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  71                 _assert(raw 
== &array
[4]); 
  74                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  78                 test_bounded_ptr
<QualT
> const ptr(array
.end(), array
.begin(), array
.end()); 
  79                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  80                 _assert(raw 
== array
.end()); 
  83                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  87                 test_bounded_ptr
<QualT
> ptr(array
.end() - 1, array
.begin(), array
.end() - 2); 
  88                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  89                 _assert(raw 
== &array
[4]); 
  92                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
  96                 test_bounded_ptr
<QualT
> ptr(array
.begin() + 1, array
.begin(), array
.end()); 
  97                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
  98                 _assert(raw 
== &array
[1]); 
 101                 // T{0}     T{1}     T{2}     T{3}     T{4}     <one-past-last> 
 105                 test_bounded_ptr
<QualT
> ptr(array
.begin(), array
.begin() + 1, array
.end()); 
 106                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
 107                 _assert(raw 
== &array
[0]); 
 110         // Test discarding the bounds of a null pointer 
 112                 test_bounded_ptr
<QualT
> const ptr(nullptr, nullptr, nullptr); 
 113                 QualT
* raw 
= ptr
.unsafe_discard_bounds(); 
 114                 _assert(raw 
== nullptr); 
 117         // Test discarding the bounds on a pointer outside of representable memory. 
 118         // Even `unsafe_discard_bounds()` will trap in such conditions. 
 120         // To do this, we setup an imaginary object with a very high address, and 
 121         // we add a large-ish offset to it, such that adding the base to the offset 
 122         // would fall outside of the representable memory. 
 124                 tracking_policy::did_trap 
= false; 
 126                 QualT
* end_of_memory 
= reinterpret_cast<QualT
*>(std::numeric_limits
<std::uintptr_t>::max()); 
 127                 QualT
* base 
= end_of_memory 
- 500; // yeah, technically UB 
 128                 std::ptrdiff_t offset 
= 501; 
 130                 libkern::bounded_ptr
<QualT
, tracking_policy
> ptr(base
, base
, base 
+ 1); 
 131                 ptr 
+= offset
; // now, `base_ + offset_` points outside of representable memory 
 133                 _assert(!tracking_policy::did_trap
); 
 134                 (void)ptr
.unsafe_discard_bounds(); 
 135                 _assert(tracking_policy::did_trap
); 
 139 T_DECL(unsafe_discard_bounds
, "bounded_ptr.unsafe_discard_bounds") { 
 142         tests
<T
, T 
volatile>(); 
 143         tests
<T
, T 
const volatile>();