TestArrayUtils.cpp (11541B)
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/. */ 6 7 #include "mozilla/ArrayUtils.h" 8 #include "mozilla/Assertions.h" 9 10 using mozilla::IsInRange; 11 12 static void TestIsInRangeNonClass() { 13 void* nul = nullptr; 14 int* intBegin = nullptr; 15 int* intEnd = intBegin + 1; 16 int* intEnd2 = intBegin + 2; 17 18 MOZ_RELEASE_ASSERT(IsInRange(nul, intBegin, intEnd)); 19 MOZ_RELEASE_ASSERT(!IsInRange(nul, intEnd, intEnd2)); 20 21 MOZ_RELEASE_ASSERT(IsInRange(intBegin, intBegin, intEnd)); 22 MOZ_RELEASE_ASSERT(!IsInRange(intEnd, intBegin, intEnd)); 23 24 MOZ_RELEASE_ASSERT(IsInRange(intBegin, intBegin, intEnd2)); 25 MOZ_RELEASE_ASSERT(IsInRange(intEnd, intBegin, intEnd2)); 26 MOZ_RELEASE_ASSERT(!IsInRange(intEnd2, intBegin, intEnd2)); 27 28 uintptr_t uintBegin = uintptr_t(intBegin); 29 uintptr_t uintEnd = uintptr_t(intEnd); 30 uintptr_t uintEnd2 = uintptr_t(intEnd2); 31 32 MOZ_RELEASE_ASSERT(IsInRange(nul, uintBegin, uintEnd)); 33 MOZ_RELEASE_ASSERT(!IsInRange(nul, uintEnd, uintEnd2)); 34 35 MOZ_RELEASE_ASSERT(IsInRange(intBegin, uintBegin, uintEnd)); 36 MOZ_RELEASE_ASSERT(!IsInRange(intEnd, uintBegin, uintEnd)); 37 38 MOZ_RELEASE_ASSERT(IsInRange(intBegin, uintBegin, uintEnd2)); 39 MOZ_RELEASE_ASSERT(IsInRange(intEnd, uintBegin, uintEnd2)); 40 MOZ_RELEASE_ASSERT(!IsInRange(intEnd2, uintBegin, uintEnd2)); 41 } 42 43 static void TestIsInRangeVoid() { 44 int* intBegin = nullptr; 45 int* intEnd = intBegin + 1; 46 int* intEnd2 = intBegin + 2; 47 48 void* voidBegin = intBegin; 49 void* voidEnd = intEnd; 50 void* voidEnd2 = intEnd2; 51 52 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, intBegin, intEnd)); 53 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, intBegin, intEnd)); 54 55 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, voidBegin, voidEnd)); 56 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, voidBegin, voidEnd)); 57 58 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, intBegin, intEnd2)); 59 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, intBegin, intEnd2)); 60 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, intBegin, intEnd2)); 61 62 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, voidBegin, voidEnd2)); 63 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, voidBegin, voidEnd2)); 64 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, voidBegin, voidEnd2)); 65 66 uintptr_t uintBegin = uintptr_t(intBegin); 67 uintptr_t uintEnd = uintptr_t(intEnd); 68 uintptr_t uintEnd2 = uintptr_t(intEnd2); 69 70 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, uintBegin, uintEnd)); 71 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd, uintBegin, uintEnd)); 72 73 MOZ_RELEASE_ASSERT(IsInRange(voidBegin, uintBegin, uintEnd2)); 74 MOZ_RELEASE_ASSERT(IsInRange(voidEnd, uintBegin, uintEnd2)); 75 MOZ_RELEASE_ASSERT(!IsInRange(voidEnd2, uintBegin, uintEnd2)); 76 } 77 78 struct Base { 79 int mX; 80 }; 81 82 static void TestIsInRangeClass() { 83 void* nul = nullptr; 84 Base* baseBegin = nullptr; 85 Base* baseEnd = baseBegin + 1; 86 Base* baseEnd2 = baseBegin + 2; 87 88 MOZ_RELEASE_ASSERT(IsInRange(nul, baseBegin, baseEnd)); 89 MOZ_RELEASE_ASSERT(!IsInRange(nul, baseEnd, baseEnd2)); 90 91 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd)); 92 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, baseBegin, baseEnd)); 93 94 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd2)); 95 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, baseBegin, baseEnd2)); 96 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, baseBegin, baseEnd2)); 97 98 uintptr_t ubaseBegin = uintptr_t(baseBegin); 99 uintptr_t ubaseEnd = uintptr_t(baseEnd); 100 uintptr_t ubaseEnd2 = uintptr_t(baseEnd2); 101 102 MOZ_RELEASE_ASSERT(IsInRange(nul, ubaseBegin, ubaseEnd)); 103 MOZ_RELEASE_ASSERT(!IsInRange(nul, ubaseEnd, ubaseEnd2)); 104 105 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd)); 106 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, ubaseBegin, ubaseEnd)); 107 108 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd2)); 109 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, ubaseBegin, ubaseEnd2)); 110 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, ubaseBegin, ubaseEnd2)); 111 } 112 113 struct EmptyBase {}; 114 115 static void TestIsInRangeEmptyClass() { 116 void* nul = nullptr; 117 EmptyBase* baseBegin = nullptr; 118 EmptyBase* baseEnd = baseBegin + 1; 119 EmptyBase* baseEnd2 = baseBegin + 2; 120 121 MOZ_RELEASE_ASSERT(IsInRange(nul, baseBegin, baseEnd)); 122 MOZ_RELEASE_ASSERT(!IsInRange(nul, baseEnd, baseEnd2)); 123 124 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd)); 125 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, baseBegin, baseEnd)); 126 127 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, baseBegin, baseEnd2)); 128 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, baseBegin, baseEnd2)); 129 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, baseBegin, baseEnd2)); 130 131 uintptr_t ubaseBegin = uintptr_t(baseBegin); 132 uintptr_t ubaseEnd = uintptr_t(baseEnd); 133 uintptr_t ubaseEnd2 = uintptr_t(baseEnd2); 134 135 MOZ_RELEASE_ASSERT(IsInRange(nul, ubaseBegin, ubaseEnd)); 136 MOZ_RELEASE_ASSERT(!IsInRange(nul, ubaseEnd, ubaseEnd2)); 137 138 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd)); 139 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, ubaseBegin, ubaseEnd)); 140 141 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, ubaseBegin, ubaseEnd2)); 142 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, ubaseBegin, ubaseEnd2)); 143 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, ubaseBegin, ubaseEnd2)); 144 } 145 146 struct Derived : Base {}; 147 148 static void TestIsInRangeClassDerived() { 149 void* nul = nullptr; 150 Derived* derivedBegin = nullptr; 151 Derived* derivedEnd = derivedBegin + 1; 152 Derived* derivedEnd2 = derivedBegin + 2; 153 154 Base* baseBegin = static_cast<Base*>(derivedBegin); 155 Base* baseEnd = static_cast<Base*>(derivedEnd); 156 Base* baseEnd2 = static_cast<Base*>(derivedEnd2); 157 158 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd)); 159 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2)); 160 161 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd)); 162 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd)); 163 164 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2)); 165 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2)); 166 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2)); 167 168 uintptr_t uderivedBegin = uintptr_t(derivedBegin); 169 uintptr_t uderivedEnd = uintptr_t(derivedEnd); 170 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2); 171 172 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd)); 173 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd)); 174 175 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2)); 176 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2)); 177 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2)); 178 } 179 180 struct DerivedEmpty : EmptyBase {}; 181 182 static void TestIsInRangeClassDerivedEmpty() { 183 void* nul = nullptr; 184 DerivedEmpty* derivedEmptyBegin = nullptr; 185 DerivedEmpty* derivedEmptyEnd = derivedEmptyBegin + 1; 186 DerivedEmpty* derivedEmptyEnd2 = derivedEmptyBegin + 2; 187 188 EmptyBase* baseBegin = static_cast<EmptyBase*>(derivedEmptyBegin); 189 EmptyBase* baseEnd = static_cast<EmptyBase*>(derivedEmptyEnd); 190 EmptyBase* baseEnd2 = static_cast<EmptyBase*>(derivedEmptyEnd2); 191 192 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedEmptyBegin, derivedEmptyEnd)); 193 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEmptyEnd, derivedEmptyEnd2)); 194 195 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedEmptyBegin, derivedEmptyEnd)); 196 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedEmptyBegin, derivedEmptyEnd)); 197 198 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedEmptyBegin, derivedEmptyEnd2)); 199 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedEmptyBegin, derivedEmptyEnd2)); 200 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedEmptyBegin, derivedEmptyEnd2)); 201 202 uintptr_t uderivedEmptyBegin = uintptr_t(derivedEmptyBegin); 203 uintptr_t uderivedEmptyEnd = uintptr_t(derivedEmptyEnd); 204 uintptr_t uderivedEmptyEnd2 = uintptr_t(derivedEmptyEnd2); 205 206 MOZ_RELEASE_ASSERT( 207 IsInRange(derivedEmptyBegin, uderivedEmptyBegin, uderivedEmptyEnd)); 208 MOZ_RELEASE_ASSERT( 209 !IsInRange(derivedEmptyEnd, uderivedEmptyBegin, uderivedEmptyEnd)); 210 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)); 217 } 218 219 struct ExtraDerived : Base { 220 int y; 221 }; 222 223 static void TestIsInRangeClassExtraDerived() { 224 void* nul = nullptr; 225 ExtraDerived* derivedBegin = nullptr; 226 ExtraDerived* derivedEnd = derivedBegin + 1; 227 ExtraDerived* derivedEnd2 = derivedBegin + 2; 228 229 Base* baseBegin = static_cast<Base*>(derivedBegin); 230 Base* baseEnd = static_cast<Base*>(derivedEnd); 231 Base* baseEnd2 = static_cast<Base*>(derivedEnd2); 232 233 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd)); 234 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2)); 235 236 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd)); 237 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd)); 238 239 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2)); 240 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2)); 241 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2)); 242 243 uintptr_t uderivedBegin = uintptr_t(derivedBegin); 244 uintptr_t uderivedEnd = uintptr_t(derivedEnd); 245 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2); 246 247 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd)); 248 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd)); 249 250 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2)); 251 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2)); 252 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2)); 253 } 254 255 struct ExtraDerivedEmpty : EmptyBase { 256 int y; 257 }; 258 259 static void TestIsInRangeClassExtraDerivedEmpty() { 260 void* nul = nullptr; 261 ExtraDerivedEmpty* derivedBegin = nullptr; 262 ExtraDerivedEmpty* derivedEnd = derivedBegin + 1; 263 ExtraDerivedEmpty* derivedEnd2 = derivedBegin + 2; 264 265 EmptyBase* baseBegin = static_cast<EmptyBase*>(derivedBegin); 266 EmptyBase* baseEnd = static_cast<EmptyBase*>(derivedEnd); 267 EmptyBase* baseEnd2 = static_cast<EmptyBase*>(derivedEnd2); 268 269 MOZ_RELEASE_ASSERT(IsInRange(nul, derivedBegin, derivedEnd)); 270 MOZ_RELEASE_ASSERT(!IsInRange(nul, derivedEnd, derivedEnd2)); 271 272 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd)); 273 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd, derivedBegin, derivedEnd)); 274 275 MOZ_RELEASE_ASSERT(IsInRange(baseBegin, derivedBegin, derivedEnd2)); 276 MOZ_RELEASE_ASSERT(IsInRange(baseEnd, derivedBegin, derivedEnd2)); 277 MOZ_RELEASE_ASSERT(!IsInRange(baseEnd2, derivedBegin, derivedEnd2)); 278 279 uintptr_t uderivedBegin = uintptr_t(derivedBegin); 280 uintptr_t uderivedEnd = uintptr_t(derivedEnd); 281 uintptr_t uderivedEnd2 = uintptr_t(derivedEnd2); 282 283 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd)); 284 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd, uderivedBegin, uderivedEnd)); 285 286 MOZ_RELEASE_ASSERT(IsInRange(derivedBegin, uderivedBegin, uderivedEnd2)); 287 MOZ_RELEASE_ASSERT(IsInRange(derivedEnd, uderivedBegin, uderivedEnd2)); 288 MOZ_RELEASE_ASSERT(!IsInRange(derivedEnd2, uderivedBegin, uderivedEnd2)); 289 } 290 291 int main() { 292 TestIsInRangeNonClass(); 293 TestIsInRangeVoid(); 294 TestIsInRangeClass(); 295 TestIsInRangeEmptyClass(); 296 TestIsInRangeClassDerived(); 297 TestIsInRangeClassDerivedEmpty(); 298 TestIsInRangeClassExtraDerived(); 299 TestIsInRangeClassExtraDerivedEmpty(); 300 return 0; 301 }