]> git.saurik.com Git - apple/xnu.git/blob - tests/bounded_ptr_src/discard_bounds.cpp
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / tests / bounded_ptr_src / discard_bounds.cpp
1 //
2 // Tests for
3 // T* discard_bounds() const;
4 //
5
6 #include <libkern/c++/bounded_ptr.h>
7 #include <array>
8 #include <darwintest.h>
9 #include <darwintest_utils.h>
10 #include "test_utils.h"
11
12 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__)
13
14 struct T { int i; };
15
16 namespace {
17 struct tracking_policy {
18 static bool did_trap;
19 static void
20 trap(char const*)
21 {
22 did_trap = true;
23 }
24 };
25 bool tracking_policy::did_trap = false;
26 }
27
28 template <typename T, typename QualT>
29 static void
30 tests()
31 {
32 std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}};
33
34 {
35 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
36 // ^ ^
37 // | |
38 // begin, ptr end
39 test_bounded_ptr<QualT> const ptr(array.begin() + 0, array.begin(), array.end());
40 QualT* raw = ptr.discard_bounds();
41 _assert(raw == &array[0]);
42 }
43 {
44 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
45 // ^ ^ ^
46 // | | |
47 // begin ptr end
48 test_bounded_ptr<QualT> const ptr(array.begin() + 1, array.begin(), array.end());
49 QualT* raw = ptr.discard_bounds();
50 _assert(raw == &array[1]);
51 }
52 {
53 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
54 // ^ ^ ^
55 // | | |
56 // begin ptr end
57 test_bounded_ptr<QualT> const ptr(array.begin() + 2, array.begin(), array.end());
58 QualT* raw = ptr.discard_bounds();
59 _assert(raw == &array[2]);
60 }
61 {
62 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
63 // ^ ^ ^
64 // | | |
65 // begin ptr end
66 test_bounded_ptr<QualT> const ptr(array.begin() + 4, array.begin(), array.end());
67 QualT* raw = ptr.discard_bounds();
68 _assert(raw == &array[4]);
69 }
70 // Make sure we don't trap when discarding the bounds of an in-bounds pointer
71 {
72 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
73 // ^ ^ ^
74 // | | |
75 // begin ptr end
76 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.begin() + 1, array.begin(), array.end());
77 tracking_policy::did_trap = false;
78 (void)*ptr;
79 (void)ptr->i;
80 _assert(!tracking_policy::did_trap);
81 }
82
83 // Make sure we trap when discarding the bounds of an out-of-bounds pointer
84 {
85 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
86 // ^ ^ ^
87 // | | |
88 // begin end ptr
89 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.end() - 1, array.begin(), array.end() - 2);
90 tracking_policy::did_trap = false;
91 (void)ptr.discard_bounds();
92 _assert(tracking_policy::did_trap);
93 }
94 {
95 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
96 // ^ ^ ^
97 // | | |
98 // ptr begin end
99 libkern::bounded_ptr<QualT, tracking_policy> ptr(array.begin(), array.begin() + 1, array.end());
100 tracking_policy::did_trap = false;
101 (void)ptr.discard_bounds();
102 _assert(tracking_policy::did_trap);
103 }
104 {
105 // T{0} T{1} T{2} T{3} T{4} <one-past-last>
106 // ^ ^ ^
107 // | (just a bit off) | |
108 // begin ptr end
109 T* t3 = const_cast<T*>(array.begin() + 3);
110 char* just_off = reinterpret_cast<char*>(t3) + 1; // 1 byte off
111 libkern::bounded_ptr<QualT, tracking_policy> ptr(reinterpret_cast<QualT*>(just_off), array.begin(), array.end() - 1);
112
113 tracking_policy::did_trap = false;
114 (void)ptr.discard_bounds();
115 _assert(tracking_policy::did_trap);
116 }
117 }
118
119 T_DECL(discard_bounds, "bounded_ptr.discard_bounds") {
120 tests<T, T>();
121 tests<T, T const>();
122 tests<T, T volatile>();
123 tests<T, T const volatile>();
124 }