1 // 2 // Tests for 3 // T& operator[](std::ptrdiff_t n) const; 4 // 5 6 #include <libkern/c++/bounded_ptr.h> 7 #include <array> 8 #include <cstddef> 9 #include <darwintest.h> 10 #include <darwintest_utils.h> 11 #include "test_utils.h" 12 13 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) 14 15 struct T { 16 int i; 17 friend constexpr bool 18 operator==(T const& a, T const& b) 19 { 20 return a.i == b.i; 21 } 22 }; 23 24 namespace { 25 struct tracking_policy { 26 static bool did_trap; 27 static void 28 trap(char const*) 29 { 30 did_trap = true; 31 } 32 }; 33 bool tracking_policy::did_trap = false; 34 } 35 36 template <typename T, typename QualT> 37 static void 38 tests() 39 { 40 std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}}; 41 42 { 43 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 44 // ^ ^ 45 // | | 46 // begin, ptr end 47 test_bounded_ptr<QualT> ptr(array.begin() + 0, array.begin(), array.end()); 48 QualT& ref0 = ptr[0]; 49 _assert(&ref0 == &array[0]); 50 51 QualT& ref1 = ptr[1]; 52 _assert(&ref1 == &array[1]); 53 54 QualT& ref2 = ptr[2]; 55 _assert(&ref2 == &array[2]); 56 57 QualT& ref3 = ptr[3]; 58 _assert(&ref3 == &array[3]); 59 60 QualT& ref4 = ptr[4]; 61 _assert(&ref4 == &array[4]); 62 } 63 { 64 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 65 // ^ ^ ^ 66 // | | | 67 // begin ptr end 68 test_bounded_ptr<QualT> ptr(array.begin() + 1, array.begin(), array.end()); 69 QualT& ref0 = ptr[-1]; 70 _assert(&ref0 == &array[0]); 71 72 QualT& ref1 = ptr[0]; 73 _assert(&ref1 == &array[1]); 74 75 QualT& ref2 = ptr[1]; 76 _assert(&ref2 == &array[2]); 77 78 QualT& ref3 = ptr[2]; 79 _assert(&ref3 == &array[3]); 80 81 QualT& ref4 = ptr[3]; 82 _assert(&ref4 == &array[4]); 83 } 84 { 85 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 86 // ^ ^ ^ 87 // | | | 88 // begin ptr end 89 test_bounded_ptr<QualT> ptr(array.begin() + 2, array.begin(), array.end()); 90 QualT& ref0 = ptr[-2]; 91 _assert(&ref0 == &array[0]); 92 93 QualT& ref1 = ptr[-1]; 94 _assert(&ref1 == &array[1]); 95 96 QualT& ref2 = ptr[0]; 97 _assert(&ref2 == &array[2]); 98 99 QualT& ref3 = ptr[1]; 100 _assert(&ref3 == &array[3]); 101 102 QualT& ref4 = ptr[2]; 103 _assert(&ref4 == &array[4]); 104 } 105 { 106 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 107 // ^ ^ ^ 108 // | | | 109 // begin ptr end 110 test_bounded_ptr<QualT> ptr(array.begin() + 4, array.begin(), array.end()); 111 QualT& ref0 = ptr[-4]; 112 _assert(&ref0 == &array[0]); 113 114 QualT& ref1 = ptr[-3]; 115 _assert(&ref1 == &array[1]); 116 117 QualT& ref2 = ptr[-2]; 118 _assert(&ref2 == &array[2]); 119 120 QualT& ref3 = ptr[-1]; 121 _assert(&ref3 == &array[3]); 122 123 QualT& ref4 = ptr[0]; 124 _assert(&ref4 == &array[4]); 125 } 126 { 127 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 128 // ^ ^ 129 // | | 130 // begin end,ptr 131 test_bounded_ptr<QualT> ptr(array.end(), array.begin(), array.end()); 132 QualT& ref0 = ptr[-5]; 133 _assert(&ref0 == &array[0]); 134 135 QualT& ref1 = ptr[-4]; 136 _assert(&ref1 == &array[1]); 137 138 QualT& ref2 = ptr[-3]; 139 _assert(&ref2 == &array[2]); 140 141 QualT& ref3 = ptr[-2]; 142 _assert(&ref3 == &array[3]); 143 144 QualT& ref4 = ptr[-1]; 145 _assert(&ref4 == &array[4]); 146 } 147 148 // Make sure we trap when we subscript a pointer at an out-of-bounds offset 149 { 150 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 151 // ^ ^ ^ 152 // | | | 153 // begin end ptr 154 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.end() - 1, array.begin(), array.end() - 2); 155 156 tracking_policy::did_trap = false; 157 (void)ptr[-4]; 158 _assert(!tracking_policy::did_trap); 159 160 tracking_policy::did_trap = false; 161 (void)ptr[-3]; 162 _assert(!tracking_policy::did_trap); 163 164 tracking_policy::did_trap = false; 165 (void)ptr[-2]; 166 _assert(!tracking_policy::did_trap); 167 168 tracking_policy::did_trap = false; 169 (void)ptr[-1]; // trap 170 _assert(tracking_policy::did_trap); 171 172 tracking_policy::did_trap = false; 173 (void)ptr[0]; // trap 174 _assert(tracking_policy::did_trap); 175 } 176 { 177 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 178 // ^ ^ ^ 179 // | | | 180 // begin ptr end 181 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.begin() + 1, array.begin(), array.end()); 182 183 tracking_policy::did_trap = false; 184 (void)ptr[-1]; 185 _assert(!tracking_policy::did_trap); 186 187 tracking_policy::did_trap = false; 188 (void)ptr[0]; 189 _assert(!tracking_policy::did_trap); 190 191 tracking_policy::did_trap = false; 192 (void)ptr[1]; 193 _assert(!tracking_policy::did_trap); 194 195 tracking_policy::did_trap = false; 196 (void)ptr[2]; 197 _assert(!tracking_policy::did_trap); 198 199 tracking_policy::did_trap = false; 200 (void)ptr[3]; 201 _assert(!tracking_policy::did_trap); 202 203 tracking_policy::did_trap = false; 204 (void)ptr[4]; // trap 205 _assert(tracking_policy::did_trap); 206 } 207 { 208 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 209 // ^ ^ ^ 210 // | | | 211 // ptr begin end 212 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.begin(), array.begin() + 1, array.end() - 1); 213 214 tracking_policy::did_trap = false; 215 (void)ptr[0]; // trap 216 _assert(tracking_policy::did_trap); 217 218 tracking_policy::did_trap = false; 219 (void)ptr[1]; 220 _assert(!tracking_policy::did_trap); 221 222 tracking_policy::did_trap = false; 223 (void)ptr[2]; 224 _assert(!tracking_policy::did_trap); 225 226 tracking_policy::did_trap = false; 227 (void)ptr[3]; 228 _assert(!tracking_policy::did_trap); 229 230 tracking_policy::did_trap = false; 231 (void)ptr[4]; // trap 232 _assert(tracking_policy::did_trap); 233 234 tracking_policy::did_trap = false; 235 (void)ptr[5]; // trap 236 _assert(tracking_policy::did_trap); 237 } 238 } 239 240 T_DECL(subscript, "bounded_ptr.subscript") { 241 tests<T, T>(); 242 tests<T, T const>(); 243 tests<T, T volatile>(); 244 tests<T, T const volatile>(); 245 246 // Make sure that we don't hard-error in the definition of operator[] 247 // when instantiating a `bounded_ptr<cv-void>` 248 test_bounded_ptr<void> p1; 249 test_bounded_ptr<void const> p2; 250 test_bounded_ptr<void volatile> p3; 251 test_bounded_ptr<void const volatile> p4; 252 } 253