Bug 1845355 - Add some asserts to detect causes of a crash r=glandium
[gecko.git] / mfbt / tests / TestArrayUtils.cpp
blobb50531a3a8b7b27b19cee404e0ae61cc7184efbb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/ArrayUtils.h"
8 #include "mozilla/Assertions.h"
10 using mozilla::IsInRange;
12 static void TestIsInRangeNonClass() {
13 void* nul = nullptr;
14 int* intBegin = nullptr;
15 int* intEnd = intBegin + 1;
16 int* intEnd2 = intBegin + 2;
18 MOZ_RELEASE_ASSERT(IsInRange(nul, intBegin, intEnd));
19 MOZ_RELEASE_ASSERT(!IsInRange(nul, intEnd, intEnd2));
21 MOZ_RELEASE_ASSERT(IsInRange(intBegin, intBegin, intEnd));
22 MOZ_RELEASE_ASSERT(!IsInRange(intEnd, intBegin, intEnd));
24 MOZ_RELEASE_ASSERT(IsInRange(intBegin, intBegin, intEnd2));
25 MOZ_RELEASE_ASSERT(IsInRange(intEnd, intBegin, intEnd2));
26 MOZ_RELEASE_ASSERT(!IsInRange(intEnd2, intBegin, intEnd2));
28 uintptr_t uintBegin = uintptr_t(intBegin);
29 uintptr_t uintEnd = uintptr_t(intEnd);
30 uintptr_t uintEnd2 = uintptr_t(intEnd2);
32 MOZ_RELEASE_ASSERT(IsInRange(nul, uintBegin, uintEnd));
33 MOZ_RELEASE_ASSERT(!IsInRange(nul, uintEnd, uintEnd2));
35 MOZ_RELEASE_ASSERT(IsInRange(intBegin, uintBegin, uintEnd));
36 MOZ_RELEASE_ASSERT(!IsInRange(intEnd, uintBegin, uintEnd));
38 MOZ_RELEASE_ASSERT(IsInRange(intBegin, uintBegin, uintEnd2));
39 MOZ_RELEASE_ASSERT(IsInRange(intEnd, uintBegin, uintEnd2));
40 MOZ_RELEASE_ASSERT(!IsInRange(intEnd2, uintBegin, uintEnd2));
43 static void TestIsInRangeVoid() {
44 int* intBegin = nullptr;
45 int* intEnd = intBegin + 1;
46 int* intEnd2 = intBegin + 2;
48 void* voidBegin = intBegin;
49 void* voidEnd = intEnd;
50 void* voidEnd2 = intEnd2;
52 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, intBegin, intEnd));
53 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, intBegin, intEnd));
55 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, voidBegin, voidEnd));
56 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, voidBegin, voidEnd));
58 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, intBegin, intEnd2));
59 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, intBegin, intEnd2));
60 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, intBegin, intEnd2));
62 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, voidBegin, voidEnd2));
63 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, voidBegin, voidEnd2));
64 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, voidBegin, voidEnd2));
66 uintptr_t uintBegin = uintptr_t(intBegin);
67 uintptr_t uintEnd = uintptr_t(intEnd);
68 uintptr_t uintEnd2 = uintptr_t(intEnd2);
70 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, uintBegin, uintEnd));
71 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, uintBegin, uintEnd));
73 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, uintBegin, uintEnd2));
74 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, uintBegin, uintEnd2));
75 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, uintBegin, uintEnd2));
78 struct Base {
79 int mX;
82 static void TestIsInRangeClass() {
83 void* nul = nullptr;
84 Base* baseBegin = nullptr;
85 Base* baseEnd = baseBegin + 1;
86 Base* baseEnd2 = baseBegin + 2;
88 MOZ_RELEASE_ASSERT(IsInRange(nul, baseBegin, baseEnd));
89 MOZ_RELEASE_ASSERT(!IsInRange(nul, baseEnd, baseEnd2));
91 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd));
92 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, baseBegin, baseEnd));
94 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd2));
95 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, baseBegin, baseEnd2));
96 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, baseBegin, baseEnd2));
98 uintptr_t ubaseBegin = uintptr_t(baseBegin);
99 uintptr_t ubaseEnd = uintptr_t(baseEnd);
100 uintptr_t ubaseEnd2 = uintptr_t(baseEnd2);
102 MOZ_RELEASE_ASSERT(IsInRange(nul, ubaseBegin, ubaseEnd));
103 MOZ_RELEASE_ASSERT(!IsInRange(nul, ubaseEnd, ubaseEnd2));
105 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd));
106 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, ubaseBegin, ubaseEnd));
108 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd2));
109 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, ubaseBegin, ubaseEnd2));
110 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, ubaseBegin, ubaseEnd2));
113 struct EmptyBase {};
115 static void TestIsInRangeEmptyClass() {
116 void* nul = nullptr;
117 EmptyBase* baseBegin = nullptr;
118 EmptyBase* baseEnd = baseBegin + 1;
119 EmptyBase* baseEnd2 = baseBegin + 2;
121 MOZ_RELEASE_ASSERT(IsInRange(nul, baseBegin, baseEnd));
122 MOZ_RELEASE_ASSERT(!IsInRange(nul, baseEnd, baseEnd2));
124 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd));
125 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, baseBegin, baseEnd));
127 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd2));
128 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, baseBegin, baseEnd2));
129 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, baseBegin, baseEnd2));
131 uintptr_t ubaseBegin = uintptr_t(baseBegin);
132 uintptr_t ubaseEnd = uintptr_t(baseEnd);
133 uintptr_t ubaseEnd2 = uintptr_t(baseEnd2);
135 MOZ_RELEASE_ASSERT(IsInRange(nul, ubaseBegin, ubaseEnd));
136 MOZ_RELEASE_ASSERT(!IsInRange(nul, ubaseEnd, ubaseEnd2));
138 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd));
139 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, ubaseBegin, ubaseEnd));
141 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd2));
142 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, ubaseBegin, ubaseEnd2));
143 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, ubaseBegin, ubaseEnd2));
146 struct Derived : Base {};
148 static void TestIsInRangeClassDerived() {
149 void* nul = nullptr;
150 Derived* derivedBegin = nullptr;
151 Derived* derivedEnd = derivedBegin + 1;
152 Derived* derivedEnd2 = derivedBegin + 2;
154 Base* baseBegin = static_cast<Base*>(derivedBegin);
155 Base* baseEnd = static_cast<Base*>(derivedEnd);
156 Base* baseEnd2 = static_cast<Base*>(derivedEnd2);
158 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd));
159 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2));
161 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd));
162 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd));
164 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2));
165 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2));
166 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2));
168 uintptr_t uderivedBegin = uintptr_t(derivedBegin);
169 uintptr_t uderivedEnd = uintptr_t(derivedEnd);
170 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2);
172 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd));
173 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd));
175 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2));
176 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2));
177 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2));
180 struct DerivedEmpty : EmptyBase {};
182 static void TestIsInRangeClassDerivedEmpty() {
183 void* nul = nullptr;
184 DerivedEmpty* derivedEmptyBegin = nullptr;
185 DerivedEmpty* derivedEmptyEnd = derivedEmptyBegin + 1;
186 DerivedEmpty* derivedEmptyEnd2 = derivedEmptyBegin + 2;
188 EmptyBase* baseBegin = static_cast<EmptyBase*>(derivedEmptyBegin);
189 EmptyBase* baseEnd = static_cast<EmptyBase*>(derivedEmptyEnd);
190 EmptyBase* baseEnd2 = static_cast<EmptyBase*>(derivedEmptyEnd2);
192 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedEmptyBegin, derivedEmptyEnd));
193 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEmptyEnd, derivedEmptyEnd2));
195 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedEmptyBegin, derivedEmptyEnd));
196 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedEmptyBegin, derivedEmptyEnd));
198 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedEmptyBegin, derivedEmptyEnd2));
199 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedEmptyBegin, derivedEmptyEnd2));
200 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedEmptyBegin, derivedEmptyEnd2));
202 uintptr_t uderivedEmptyBegin = uintptr_t(derivedEmptyBegin);
203 uintptr_t uderivedEmptyEnd = uintptr_t(derivedEmptyEnd);
204 uintptr_t uderivedEmptyEnd2 = uintptr_t(derivedEmptyEnd2);
206 MOZ_RELEASE_ASSERT(
207 IsInRange(derivedEmptyBegin, uderivedEmptyBegin, uderivedEmptyEnd));
208 MOZ_RELEASE_ASSERT(
209 !IsInRange(derivedEmptyEnd, uderivedEmptyBegin, uderivedEmptyEnd));
211 MOZ_RELEASE_ASSERT(
212 IsInRange(derivedEmptyBegin, uderivedEmptyBegin, uderivedEmptyEnd2));
213 MOZ_RELEASE_ASSERT(
214 IsInRange(derivedEmptyEnd, uderivedEmptyBegin, uderivedEmptyEnd2));
215 MOZ_RELEASE_ASSERT(
216 !IsInRange(derivedEmptyEnd2, uderivedEmptyBegin, uderivedEmptyEnd2));
219 struct ExtraDerived : Base {
220 int y;
223 static void TestIsInRangeClassExtraDerived() {
224 void* nul = nullptr;
225 ExtraDerived* derivedBegin = nullptr;
226 ExtraDerived* derivedEnd = derivedBegin + 1;
227 ExtraDerived* derivedEnd2 = derivedBegin + 2;
229 Base* baseBegin = static_cast<Base*>(derivedBegin);
230 Base* baseEnd = static_cast<Base*>(derivedEnd);
231 Base* baseEnd2 = static_cast<Base*>(derivedEnd2);
233 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd));
234 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2));
236 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd));
237 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd));
239 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2));
240 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2));
241 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2));
243 uintptr_t uderivedBegin = uintptr_t(derivedBegin);
244 uintptr_t uderivedEnd = uintptr_t(derivedEnd);
245 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2);
247 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd));
248 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd));
250 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2));
251 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2));
252 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2));
255 struct ExtraDerivedEmpty : EmptyBase {
256 int y;
259 static void TestIsInRangeClassExtraDerivedEmpty() {
260 void* nul = nullptr;
261 ExtraDerivedEmpty* derivedBegin = nullptr;
262 ExtraDerivedEmpty* derivedEnd = derivedBegin + 1;
263 ExtraDerivedEmpty* derivedEnd2 = derivedBegin + 2;
265 EmptyBase* baseBegin = static_cast<EmptyBase*>(derivedBegin);
266 EmptyBase* baseEnd = static_cast<EmptyBase*>(derivedEnd);
267 EmptyBase* baseEnd2 = static_cast<EmptyBase*>(derivedEnd2);
269 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd));
270 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2));
272 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd));
273 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd));
275 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2));
276 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2));
277 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2));
279 uintptr_t uderivedBegin = uintptr_t(derivedBegin);
280 uintptr_t uderivedEnd = uintptr_t(derivedEnd);
281 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2);
283 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd));
284 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd));
286 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2));
287 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2));
288 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2));
291 int main() {
292 TestIsInRangeNonClass();
293 TestIsInRangeVoid();
294 TestIsInRangeClass();
295 TestIsInRangeEmptyClass();
296 TestIsInRangeClassDerived();
297 TestIsInRangeClassDerivedEmpty();
298 TestIsInRangeClassExtraDerived();
299 TestIsInRangeClassExtraDerivedEmpty();
300 return 0;