tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestWrappingOperations.cpp (25913B)


      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/Assertions.h"
      8 #include "mozilla/WrappingOperations.h"
      9 
     10 #include <stdint.h>
     11 
     12 using mozilla::WrappingAdd;
     13 using mozilla::WrappingMultiply;
     14 using mozilla::WrappingSubtract;
     15 using mozilla::WrapToSigned;
     16 
     17 // NOTE: In places below |-FOO_MAX - 1| is used instead of |-FOO_MIN| because
     18 //       in C++ numeric literals are full expressions -- the |-| in a negative
     19 //       number is technically separate.  So with most compilers that limit
     20 //       |int| to the signed 32-bit range, something like |-2147483648| is
     21 //       operator-() applied to an *unsigned* expression.  And MSVC, at least,
     22 //       warns when you do that.  (The operation is well-defined, but it likely
     23 //       doesn't do what was intended.)  So we do the usual workaround for this
     24 //       (see your local copy of <stdint.h> for a likely demo of this), writing
     25 //       it out by negating the max value and subtracting 1.
     26 
     27 static_assert(WrapToSigned(uint8_t(17)) == 17,
     28              "no wraparound should work, 8-bit");
     29 static_assert(WrapToSigned(uint8_t(128)) == -128,
     30              "works for 8-bit numbers, wraparound low end");
     31 static_assert(WrapToSigned(uint8_t(128 + 7)) == -128 + 7,
     32              "works for 8-bit numbers, wraparound mid");
     33 static_assert(WrapToSigned(uint8_t(128 + 127)) == -128 + 127,
     34              "works for 8-bit numbers, wraparound high end");
     35 
     36 static_assert(WrapToSigned(uint16_t(12345)) == 12345,
     37              "no wraparound should work, 16-bit");
     38 static_assert(WrapToSigned(uint16_t(32768)) == -32768,
     39              "works for 16-bit numbers, wraparound low end");
     40 static_assert(WrapToSigned(uint16_t(32768 + 42)) == -32768 + 42,
     41              "works for 16-bit numbers, wraparound mid");
     42 static_assert(WrapToSigned(uint16_t(32768 + 32767)) == -32768 + 32767,
     43              "works for 16-bit numbers, wraparound high end");
     44 
     45 static_assert(WrapToSigned(uint32_t(8675309)) == 8675309,
     46              "no wraparound should work, 32-bit");
     47 static_assert(WrapToSigned(uint32_t(2147483648)) == -2147483647 - 1,
     48              "works for 32-bit numbers, wraparound low end");
     49 static_assert(WrapToSigned(uint32_t(2147483648 + 42)) == -2147483647 - 1 + 42,
     50              "works for 32-bit numbers, wraparound mid");
     51 static_assert(WrapToSigned(uint32_t(2147483648 + 2147483647)) ==
     52                  -2147483647 - 1 + 2147483647,
     53              "works for 32-bit numbers, wraparound high end");
     54 
     55 static_assert(WrapToSigned(uint64_t(4152739164)) == 4152739164,
     56              "no wraparound should work, 64-bit");
     57 static_assert(WrapToSigned(uint64_t(9223372036854775808ULL)) ==
     58                  -9223372036854775807LL - 1,
     59              "works for 64-bit numbers, wraparound low end");
     60 static_assert(WrapToSigned(uint64_t(9223372036854775808ULL + 8005552368LL)) ==
     61                  -9223372036854775807LL - 1 + 8005552368LL,
     62              "works for 64-bit numbers, wraparound mid");
     63 static_assert(WrapToSigned(uint64_t(9223372036854775808ULL +
     64                                    9223372036854775807ULL)) ==
     65                  -9223372036854775807LL - 1 + 9223372036854775807LL,
     66              "works for 64-bit numbers, wraparound high end");
     67 
     68 template <typename T>
     69 inline constexpr bool TestEqual(T aX, T aY) {
     70  return aX == aY;
     71 }
     72 
     73 static void TestWrappingAdd8() {
     74  MOZ_RELEASE_ASSERT(
     75      TestEqual(WrappingAdd(uint8_t(0), uint8_t(128)), uint8_t(128)),
     76      "zero plus anything is anything");
     77  MOZ_RELEASE_ASSERT(
     78      TestEqual(WrappingAdd(uint8_t(17), uint8_t(42)), uint8_t(59)),
     79      "17 + 42 == 59");
     80  MOZ_RELEASE_ASSERT(
     81      TestEqual(WrappingAdd(uint8_t(255), uint8_t(1)), uint8_t(0)),
     82      "all bits plus one overflows to zero");
     83  MOZ_RELEASE_ASSERT(
     84      TestEqual(WrappingAdd(uint8_t(128), uint8_t(127)), uint8_t(255)),
     85      "high bit plus all lower bits is all bits");
     86  MOZ_RELEASE_ASSERT(
     87      TestEqual(WrappingAdd(uint8_t(128), uint8_t(193)), uint8_t(65)),
     88      "128 + 193 is 256 + 65");
     89 
     90  MOZ_RELEASE_ASSERT(
     91      TestEqual(WrappingAdd(int8_t(0), int8_t(-128)), int8_t(-128)),
     92      "zero plus anything is anything");
     93  MOZ_RELEASE_ASSERT(
     94      TestEqual(WrappingAdd(int8_t(123), int8_t(8)), int8_t(-125)),
     95      "overflow to negative");
     96  MOZ_RELEASE_ASSERT(
     97      TestEqual(WrappingAdd(int8_t(5), int8_t(-123)), int8_t(-118)),
     98      "5 - 123 is -118");
     99  MOZ_RELEASE_ASSERT(
    100      TestEqual(WrappingAdd(int8_t(-85), int8_t(-73)), int8_t(98)),
    101      "underflow to positive");
    102  MOZ_RELEASE_ASSERT(
    103      TestEqual(WrappingAdd(int8_t(-128), int8_t(127)), int8_t(-1)),
    104      "high bit plus all lower bits is -1");
    105 }
    106 
    107 static void TestWrappingAdd16() {
    108  MOZ_RELEASE_ASSERT(
    109      TestEqual(WrappingAdd(uint16_t(0), uint16_t(32768)), uint16_t(32768)),
    110      "zero plus anything is anything");
    111  MOZ_RELEASE_ASSERT(
    112      TestEqual(WrappingAdd(uint16_t(24389), uint16_t(2682)), uint16_t(27071)),
    113      "24389 + 2682 == 27071");
    114  MOZ_RELEASE_ASSERT(
    115      TestEqual(WrappingAdd(uint16_t(65535), uint16_t(1)), uint16_t(0)),
    116      "all bits plus one overflows to zero");
    117  MOZ_RELEASE_ASSERT(
    118      TestEqual(WrappingAdd(uint16_t(32768), uint16_t(32767)), uint16_t(65535)),
    119      "high bit plus all lower bits is all bits");
    120  MOZ_RELEASE_ASSERT(
    121      TestEqual(WrappingAdd(uint16_t(32768), uint16_t(47582)), uint16_t(14814)),
    122      "32768 + 47582 is 65536 + 14814");
    123 
    124  MOZ_RELEASE_ASSERT(
    125      TestEqual(WrappingAdd(int16_t(0), int16_t(-32768)), int16_t(-32768)),
    126      "zero plus anything is anything");
    127  MOZ_RELEASE_ASSERT(
    128      TestEqual(WrappingAdd(int16_t(32765), int16_t(8)), int16_t(-32763)),
    129      "overflow to negative");
    130  MOZ_RELEASE_ASSERT(
    131      TestEqual(WrappingAdd(int16_t(5), int16_t(-28933)), int16_t(-28928)),
    132      "5 - 28933 is -28928");
    133  MOZ_RELEASE_ASSERT(
    134      TestEqual(WrappingAdd(int16_t(-23892), int16_t(-12893)), int16_t(28751)),
    135      "underflow to positive");
    136  MOZ_RELEASE_ASSERT(
    137      TestEqual(WrappingAdd(int16_t(-32768), int16_t(32767)), int16_t(-1)),
    138      "high bit plus all lower bits is -1");
    139 }
    140 
    141 static void TestWrappingAdd32() {
    142  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(uint32_t(0), uint32_t(2147483648)),
    143                               uint32_t(2147483648)),
    144                     "zero plus anything is anything");
    145  MOZ_RELEASE_ASSERT(
    146      TestEqual(WrappingAdd(uint32_t(1398742328), uint32_t(714192829)),
    147                uint32_t(2112935157)),
    148      "1398742328 + 714192829 == 2112935157");
    149  MOZ_RELEASE_ASSERT(
    150      TestEqual(WrappingAdd(uint32_t(4294967295), uint32_t(1)), uint32_t(0)),
    151      "all bits plus one overflows to zero");
    152  MOZ_RELEASE_ASSERT(
    153      TestEqual(WrappingAdd(uint32_t(2147483648), uint32_t(2147483647)),
    154                uint32_t(4294967295)),
    155      "high bit plus all lower bits is all bits");
    156  MOZ_RELEASE_ASSERT(
    157      TestEqual(WrappingAdd(uint32_t(2147483648), uint32_t(3146492712)),
    158                uint32_t(999009064)),
    159      "2147483648 + 3146492712 is 4294967296 + 999009064");
    160 
    161  MOZ_RELEASE_ASSERT(
    162      TestEqual(WrappingAdd(int32_t(0), int32_t(-2147483647 - 1)),
    163                int32_t(-2147483647 - 1)),
    164      "zero plus anything is anything");
    165  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(int32_t(2147483645), int32_t(8)),
    166                               int32_t(-2147483643)),
    167                     "overflow to negative");
    168  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(int32_t(257), int32_t(-23947248)),
    169                               int32_t(-23946991)),
    170                     "257 - 23947248 is -23946991");
    171  MOZ_RELEASE_ASSERT(
    172      TestEqual(WrappingAdd(int32_t(-2147483220), int32_t(-12893)),
    173                int32_t(2147471183)),
    174      "underflow to positive");
    175  MOZ_RELEASE_ASSERT(
    176      TestEqual(WrappingAdd(int32_t(-32768), int32_t(32767)), int32_t(-1)),
    177      "high bit plus all lower bits is -1");
    178 }
    179 
    180 static void TestWrappingAdd64() {
    181  MOZ_RELEASE_ASSERT(
    182      TestEqual(WrappingAdd(uint64_t(0), uint64_t(9223372036854775808ULL)),
    183                uint64_t(9223372036854775808ULL)),
    184      "zero plus anything is anything");
    185  MOZ_RELEASE_ASSERT(
    186      TestEqual(WrappingAdd(uint64_t(70368744177664), uint64_t(3740873592)),
    187                uint64_t(70372485051256)),
    188      "70368744177664 + 3740873592 == 70372485051256");
    189  MOZ_RELEASE_ASSERT(
    190      TestEqual(WrappingAdd(uint64_t(18446744073709551615ULL), uint64_t(1)),
    191                uint64_t(0)),
    192      "all bits plus one overflows to zero");
    193  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(uint64_t(9223372036854775808ULL),
    194                                           uint64_t(9223372036854775807ULL)),
    195                               uint64_t(18446744073709551615ULL)),
    196                     "high bit plus all lower bits is all bits");
    197  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(uint64_t(14552598638644786479ULL),
    198                                           uint64_t(3894174382537247221ULL)),
    199                               uint64_t(28947472482084)),
    200                     "9223372036854775808 + 3146492712 is 18446744073709551616 "
    201                     "+ 28947472482084");
    202 
    203  MOZ_RELEASE_ASSERT(
    204      TestEqual(WrappingAdd(int64_t(0), int64_t(-9223372036854775807LL - 1)),
    205                int64_t(-9223372036854775807LL - 1)),
    206      "zero plus anything is anything");
    207  MOZ_RELEASE_ASSERT(
    208      TestEqual(WrappingAdd(int64_t(9223372036854775802LL), int64_t(8)),
    209                int64_t(-9223372036854775806LL)),
    210      "overflow to negative");
    211  MOZ_RELEASE_ASSERT(
    212      TestEqual(WrappingAdd(int64_t(37482739294298742LL),
    213                            int64_t(-437843573929483498LL)),
    214                int64_t(-400360834635184756LL)),
    215      "37482739294298742 - 437843573929483498 is -400360834635184756");
    216  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(int64_t(-9127837934058953374LL),
    217                                           int64_t(-4173572032144775807LL)),
    218                               int64_t(5145334107505822435L)),
    219                     "underflow to positive");
    220  MOZ_RELEASE_ASSERT(TestEqual(WrappingAdd(int64_t(-9223372036854775807LL - 1),
    221                                           int64_t(9223372036854775807LL)),
    222                               int64_t(-1)),
    223                     "high bit plus all lower bits is -1");
    224 }
    225 
    226 static void TestWrappingAdd() {
    227  TestWrappingAdd8();
    228  TestWrappingAdd16();
    229  TestWrappingAdd32();
    230  TestWrappingAdd64();
    231 }
    232 
    233 static void TestWrappingSubtract8() {
    234  MOZ_RELEASE_ASSERT(
    235      TestEqual(WrappingSubtract(uint8_t(0), uint8_t(128)), uint8_t(128)),
    236      "zero minus half is half");
    237  MOZ_RELEASE_ASSERT(
    238      TestEqual(WrappingSubtract(uint8_t(17), uint8_t(42)), uint8_t(231)),
    239      "17 - 42 == -25 added to 256 is 231");
    240  MOZ_RELEASE_ASSERT(
    241      TestEqual(WrappingSubtract(uint8_t(0), uint8_t(1)), uint8_t(255)),
    242      "zero underflows to all bits");
    243  MOZ_RELEASE_ASSERT(
    244      TestEqual(WrappingSubtract(uint8_t(128), uint8_t(127)), uint8_t(1)),
    245      "128 - 127 == 1");
    246  MOZ_RELEASE_ASSERT(
    247      TestEqual(WrappingSubtract(uint8_t(128), uint8_t(193)), uint8_t(191)),
    248      "128 - 193 is -65 so -65 + 256 == 191");
    249 
    250  MOZ_RELEASE_ASSERT(
    251      TestEqual(WrappingSubtract(int8_t(0), int8_t(-128)), int8_t(-128)),
    252      "zero minus high bit wraps to high bit");
    253  MOZ_RELEASE_ASSERT(
    254      TestEqual(WrappingSubtract(int8_t(-126), int8_t(4)), int8_t(126)),
    255      "underflow to positive");
    256  MOZ_RELEASE_ASSERT(
    257      TestEqual(WrappingSubtract(int8_t(5), int8_t(-123)), int8_t(-128)),
    258      "overflow to negative");
    259  MOZ_RELEASE_ASSERT(
    260      TestEqual(WrappingSubtract(int8_t(-85), int8_t(-73)), int8_t(-12)),
    261      "negative minus smaller negative");
    262  MOZ_RELEASE_ASSERT(
    263      TestEqual(WrappingSubtract(int8_t(-128), int8_t(127)), int8_t(1)),
    264      "underflow to 1");
    265 }
    266 
    267 static void TestWrappingSubtract16() {
    268  MOZ_RELEASE_ASSERT(TestEqual(WrappingSubtract(uint16_t(0), uint16_t(32768)),
    269                               uint16_t(32768)),
    270                     "zero minus half is half");
    271  MOZ_RELEASE_ASSERT(
    272      TestEqual(WrappingSubtract(uint16_t(24389), uint16_t(2682)),
    273                uint16_t(21707)),
    274      "24389 - 2682 == 21707");
    275  MOZ_RELEASE_ASSERT(
    276      TestEqual(WrappingSubtract(uint16_t(0), uint16_t(1)), uint16_t(65535)),
    277      "zero underflows to all bits");
    278  MOZ_RELEASE_ASSERT(
    279      TestEqual(WrappingSubtract(uint16_t(32768), uint16_t(32767)),
    280                uint16_t(1)),
    281      "high bit minus all lower bits is one");
    282  MOZ_RELEASE_ASSERT(
    283      TestEqual(WrappingSubtract(uint16_t(32768), uint16_t(47582)),
    284                uint16_t(50722)),
    285      "32768 - 47582 + 65536 is 50722");
    286 
    287  MOZ_RELEASE_ASSERT(
    288      TestEqual(WrappingSubtract(int16_t(0), int16_t(-32768)), int16_t(-32768)),
    289      "zero minus high bit wraps to high bit");
    290  MOZ_RELEASE_ASSERT(
    291      TestEqual(WrappingSubtract(int16_t(-32766), int16_t(4)), int16_t(32766)),
    292      "underflow to positive");
    293  MOZ_RELEASE_ASSERT(
    294      TestEqual(WrappingSubtract(int16_t(5), int16_t(-28933)), int16_t(28938)),
    295      "5 - -28933 is 28938");
    296  MOZ_RELEASE_ASSERT(
    297      TestEqual(WrappingSubtract(int16_t(-23892), int16_t(-12893)),
    298                int16_t(-10999)),
    299      "negative minus smaller negative");
    300  MOZ_RELEASE_ASSERT(
    301      TestEqual(WrappingSubtract(int16_t(-32768), int16_t(32767)), int16_t(1)),
    302      "underflow to 1");
    303 }
    304 
    305 static void TestWrappingSubtract32() {
    306  MOZ_RELEASE_ASSERT(
    307      TestEqual(WrappingSubtract(uint32_t(0), uint32_t(2147483648)),
    308                uint32_t(2147483648)),
    309      "zero minus half is half");
    310  MOZ_RELEASE_ASSERT(
    311      TestEqual(WrappingSubtract(uint32_t(1398742328), uint32_t(714192829)),
    312                uint32_t(684549499)),
    313      "1398742328 - 714192829 == 684549499");
    314  MOZ_RELEASE_ASSERT(TestEqual(WrappingSubtract(uint32_t(0), uint32_t(1)),
    315                               uint32_t(4294967295)),
    316                     "zero underflows to all bits");
    317  MOZ_RELEASE_ASSERT(
    318      TestEqual(WrappingSubtract(uint32_t(2147483648), uint32_t(2147483647)),
    319                uint32_t(1)),
    320      "high bit minus all lower bits is one");
    321  MOZ_RELEASE_ASSERT(
    322      TestEqual(WrappingSubtract(uint32_t(2147483648), uint32_t(3146492712)),
    323                uint32_t(3295958232)),
    324      "2147483648 - 3146492712 + 4294967296 is 3295958232");
    325 
    326  MOZ_RELEASE_ASSERT(
    327      TestEqual(WrappingSubtract(int32_t(0), int32_t(-2147483647 - 1)),
    328                int32_t(-2147483647 - 1)),
    329      "zero minus high bit wraps to high bit");
    330  MOZ_RELEASE_ASSERT(
    331      TestEqual(WrappingSubtract(int32_t(-2147483646), int32_t(4)),
    332                int32_t(2147483646)),
    333      "underflow to positive");
    334  MOZ_RELEASE_ASSERT(
    335      TestEqual(WrappingSubtract(int32_t(257), int32_t(-23947248)),
    336                int32_t(23947505)),
    337      "257 - -23947248 is 23947505");
    338  MOZ_RELEASE_ASSERT(
    339      TestEqual(WrappingSubtract(int32_t(-2147483220), int32_t(-12893)),
    340                int32_t(-2147470327)),
    341      "negative minus smaller negative");
    342  MOZ_RELEASE_ASSERT(
    343      TestEqual(WrappingSubtract(int32_t(-2147483647 - 1), int32_t(2147483647)),
    344                int32_t(1)),
    345      "underflow to 1");
    346 }
    347 
    348 static void TestWrappingSubtract64() {
    349  MOZ_RELEASE_ASSERT(
    350      TestEqual(WrappingSubtract(uint64_t(0), uint64_t(9223372036854775808ULL)),
    351                uint64_t(9223372036854775808ULL)),
    352      "zero minus half is half");
    353  MOZ_RELEASE_ASSERT(TestEqual(WrappingSubtract(uint64_t(70368744177664),
    354                                                uint64_t(3740873592)),
    355                               uint64_t(70365003304072)),
    356                     "70368744177664 - 3740873592 == 70365003304072");
    357  MOZ_RELEASE_ASSERT(TestEqual(WrappingSubtract(uint64_t(0), uint64_t(1)),
    358                               uint64_t(18446744073709551615ULL)),
    359                     "zero underflows to all bits");
    360  MOZ_RELEASE_ASSERT(
    361      TestEqual(WrappingSubtract(uint64_t(9223372036854775808ULL),
    362                                 uint64_t(9223372036854775807ULL)),
    363                uint64_t(1)),
    364      "high bit minus all lower bits is one");
    365  MOZ_RELEASE_ASSERT(
    366      TestEqual(WrappingSubtract(uint64_t(14552598638644786479ULL),
    367                                 uint64_t(3894174382537247221ULL)),
    368                uint64_t(10658424256107539258ULL)),
    369      "14552598638644786479 - 39763621533397112216 is 10658424256107539258L");
    370 
    371  MOZ_RELEASE_ASSERT(
    372      TestEqual(
    373          WrappingSubtract(int64_t(0), int64_t(-9223372036854775807LL - 1)),
    374          int64_t(-9223372036854775807LL - 1)),
    375      "zero minus high bit wraps to high bit");
    376  MOZ_RELEASE_ASSERT(
    377      TestEqual(WrappingSubtract(int64_t(-9223372036854775802LL), int64_t(8)),
    378                int64_t(9223372036854775806LL)),
    379      "overflow to negative");
    380  MOZ_RELEASE_ASSERT(
    381      TestEqual(WrappingSubtract(int64_t(37482739294298742LL),
    382                                 int64_t(-437843573929483498LL)),
    383                int64_t(475326313223782240)),
    384      "37482739294298742 - -437843573929483498 is 475326313223782240");
    385  MOZ_RELEASE_ASSERT(
    386      TestEqual(WrappingSubtract(int64_t(-9127837934058953374LL),
    387                                 int64_t(-4173572032144775807LL)),
    388                int64_t(-4954265901914177567LL)),
    389      "negative minus smaller negative");
    390  MOZ_RELEASE_ASSERT(
    391      TestEqual(WrappingSubtract(int64_t(-9223372036854775807LL - 1),
    392                                 int64_t(9223372036854775807LL)),
    393                int64_t(1)),
    394      "underflow to 1");
    395 }
    396 
    397 static void TestWrappingSubtract() {
    398  TestWrappingSubtract8();
    399  TestWrappingSubtract16();
    400  TestWrappingSubtract32();
    401  TestWrappingSubtract64();
    402 }
    403 
    404 static void TestWrappingMultiply8() {
    405  MOZ_RELEASE_ASSERT(
    406      TestEqual(WrappingMultiply(uint8_t(0), uint8_t(128)), uint8_t(0)),
    407      "zero times anything is zero");
    408  MOZ_RELEASE_ASSERT(
    409      TestEqual(WrappingMultiply(uint8_t(128), uint8_t(1)), uint8_t(128)),
    410      "1 times anything is anything");
    411  MOZ_RELEASE_ASSERT(
    412      TestEqual(WrappingMultiply(uint8_t(2), uint8_t(128)), uint8_t(0)),
    413      "2 times high bit overflows, produces zero");
    414  MOZ_RELEASE_ASSERT(
    415      TestEqual(WrappingMultiply(uint8_t(8), uint8_t(16)), uint8_t(128)),
    416      "multiply that populates the high bit produces that value");
    417  MOZ_RELEASE_ASSERT(
    418      TestEqual(WrappingMultiply(uint8_t(127), uint8_t(127)), uint8_t(1)),
    419      "multiplying signed maxvals overflows all the way to 1");
    420 
    421  MOZ_RELEASE_ASSERT(
    422      TestEqual(WrappingMultiply(int8_t(0), int8_t(-128)), int8_t(0)),
    423      "zero times anything is zero");
    424  MOZ_RELEASE_ASSERT(
    425      TestEqual(WrappingMultiply(int8_t(-128), int8_t(1)), int8_t(-128)),
    426      "1 times anything is anything");
    427  MOZ_RELEASE_ASSERT(
    428      TestEqual(WrappingMultiply(int8_t(2), int8_t(-128)), int8_t(0)),
    429      "2 times min overflows, produces zero");
    430  MOZ_RELEASE_ASSERT(
    431      TestEqual(WrappingMultiply(int8_t(16), int8_t(24)), int8_t(-128)),
    432      "multiply that populates the sign bit produces minval");
    433  MOZ_RELEASE_ASSERT(
    434      TestEqual(WrappingMultiply(int8_t(8), int8_t(16)), int8_t(-128)),
    435      "multiply that populates the sign bit produces minval");
    436  MOZ_RELEASE_ASSERT(
    437      TestEqual(WrappingMultiply(int8_t(127), int8_t(127)), int8_t(1)),
    438      "multiplying maxvals overflows all the way to 1");
    439 }
    440 
    441 static void TestWrappingMultiply16() {
    442  MOZ_RELEASE_ASSERT(
    443      TestEqual(WrappingMultiply(uint16_t(0), uint16_t(32768)), uint16_t(0)),
    444      "zero times anything is zero");
    445  MOZ_RELEASE_ASSERT(TestEqual(WrappingMultiply(uint16_t(32768), uint16_t(1)),
    446                               uint16_t(32768)),
    447                     "1 times anything is anything");
    448  MOZ_RELEASE_ASSERT(
    449      TestEqual(WrappingMultiply(uint16_t(2), uint16_t(32768)), uint16_t(0)),
    450      "2 times high bit overflows, produces zero");
    451  MOZ_RELEASE_ASSERT(TestEqual(WrappingMultiply(uint16_t(3), uint16_t(32768)),
    452                               uint16_t(-32768)),
    453                     "3 * 32768 - 65536 is 32768");
    454  MOZ_RELEASE_ASSERT(
    455      TestEqual(WrappingMultiply(uint16_t(64), uint16_t(512)), uint16_t(32768)),
    456      "multiply that populates the high bit produces that value");
    457  MOZ_RELEASE_ASSERT(
    458      TestEqual(WrappingMultiply(uint16_t(32767), uint16_t(32767)),
    459                uint16_t(1)),
    460      "multiplying signed maxvals overflows all the way to 1");
    461 
    462  MOZ_RELEASE_ASSERT(
    463      TestEqual(WrappingMultiply(int16_t(0), int16_t(-32768)), int16_t(0)),
    464      "zero times anything is zero");
    465  MOZ_RELEASE_ASSERT(
    466      TestEqual(WrappingMultiply(int16_t(-32768), int16_t(1)), int16_t(-32768)),
    467      "1 times anything is anything");
    468  MOZ_RELEASE_ASSERT(
    469      TestEqual(WrappingMultiply(int16_t(-456), int16_t(123)), int16_t(9448)),
    470      "multiply opposite signs, then add 2**16 for the result");
    471  MOZ_RELEASE_ASSERT(
    472      TestEqual(WrappingMultiply(int16_t(2), int16_t(-32768)), int16_t(0)),
    473      "2 times min overflows, produces zero");
    474  MOZ_RELEASE_ASSERT(
    475      TestEqual(WrappingMultiply(int16_t(64), int16_t(512)), int16_t(-32768)),
    476      "multiply that populates the sign bit produces minval");
    477  MOZ_RELEASE_ASSERT(
    478      TestEqual(WrappingMultiply(int16_t(32767), int16_t(32767)), int16_t(1)),
    479      "multiplying maxvals overflows all the way to 1");
    480 }
    481 
    482 static void TestWrappingMultiply32() {
    483  MOZ_RELEASE_ASSERT(
    484      TestEqual(WrappingMultiply(uint32_t(0), uint32_t(2147483648)),
    485                uint32_t(0)),
    486      "zero times anything is zero");
    487  MOZ_RELEASE_ASSERT(
    488      TestEqual(WrappingMultiply(uint32_t(42), uint32_t(17)), uint32_t(714)),
    489      "42 * 17 is 714 without wraparound");
    490  MOZ_RELEASE_ASSERT(
    491      TestEqual(WrappingMultiply(uint32_t(2147483648), uint32_t(1)),
    492                uint32_t(2147483648)),
    493      "1 times anything is anything");
    494  MOZ_RELEASE_ASSERT(
    495      TestEqual(WrappingMultiply(uint32_t(2), uint32_t(2147483648)),
    496                uint32_t(0)),
    497      "2 times high bit overflows, produces zero");
    498  MOZ_RELEASE_ASSERT(
    499      TestEqual(WrappingMultiply(uint32_t(8192), uint32_t(262144)),
    500                uint32_t(2147483648)),
    501      "multiply that populates the high bit produces that value");
    502  MOZ_RELEASE_ASSERT(
    503      TestEqual(WrappingMultiply(uint32_t(2147483647), uint32_t(2147483647)),
    504                uint32_t(1)),
    505      "multiplying signed maxvals overflows all the way to 1");
    506 
    507  MOZ_RELEASE_ASSERT(
    508      TestEqual(WrappingMultiply(int32_t(0), int32_t(-2147483647 - 1)),
    509                int32_t(0)),
    510      "zero times anything is zero");
    511  MOZ_RELEASE_ASSERT(
    512      TestEqual(WrappingMultiply(int32_t(-2147483647 - 1), int32_t(1)),
    513                int32_t(-2147483647 - 1)),
    514      "1 times anything is anything");
    515  MOZ_RELEASE_ASSERT(
    516      TestEqual(WrappingMultiply(int32_t(2), int32_t(-2147483647 - 1)),
    517                int32_t(0)),
    518      "2 times min overflows, produces zero");
    519  MOZ_RELEASE_ASSERT(
    520      TestEqual(WrappingMultiply(int32_t(-7), int32_t(-9)), int32_t(63)),
    521      "-7 * -9 is 63, no wraparound needed");
    522  MOZ_RELEASE_ASSERT(TestEqual(WrappingMultiply(int32_t(8192), int32_t(262144)),
    523                               int32_t(-2147483647 - 1)),
    524                     "multiply that populates the sign bit produces minval");
    525  MOZ_RELEASE_ASSERT(
    526      TestEqual(WrappingMultiply(int32_t(2147483647), int32_t(2147483647)),
    527                int32_t(1)),
    528      "multiplying maxvals overflows all the way to 1");
    529 }
    530 
    531 static void TestWrappingMultiply64() {
    532  MOZ_RELEASE_ASSERT(
    533      TestEqual(WrappingMultiply(uint64_t(0), uint64_t(9223372036854775808ULL)),
    534                uint64_t(0)),
    535      "zero times anything is zero");
    536  MOZ_RELEASE_ASSERT(
    537      TestEqual(WrappingMultiply(uint64_t(9223372036854775808ULL), uint64_t(1)),
    538                uint64_t(9223372036854775808ULL)),
    539      "1 times anything is anything");
    540  MOZ_RELEASE_ASSERT(
    541      TestEqual(WrappingMultiply(uint64_t(2), uint64_t(9223372036854775808ULL)),
    542                uint64_t(0)),
    543      "2 times high bit overflows, produces zero");
    544  MOZ_RELEASE_ASSERT(
    545      TestEqual(WrappingMultiply(uint64_t(131072), uint64_t(70368744177664)),
    546                uint64_t(9223372036854775808ULL)),
    547      "multiply that populates the high bit produces that value");
    548  MOZ_RELEASE_ASSERT(TestEqual(WrappingMultiply(uint64_t(9223372036854775807),
    549                                                uint64_t(9223372036854775807)),
    550                               uint64_t(1)),
    551                     "multiplying signed maxvals overflows all the way to 1");
    552 
    553  MOZ_RELEASE_ASSERT(
    554      TestEqual(WrappingMultiply(int64_t(0), int64_t(-9223372036854775807 - 1)),
    555                int64_t(0)),
    556      "zero times anything is zero");
    557  MOZ_RELEASE_ASSERT(
    558      TestEqual(WrappingMultiply(int64_t(-9223372036854775807 - 1), int64_t(1)),
    559                int64_t(-9223372036854775807 - 1)),
    560      "1 times anything is anything");
    561  MOZ_RELEASE_ASSERT(
    562      TestEqual(WrappingMultiply(int64_t(2), int64_t(-9223372036854775807 - 1)),
    563                int64_t(0)),
    564      "2 times min overflows, produces zero");
    565  MOZ_RELEASE_ASSERT(
    566      TestEqual(WrappingMultiply(int64_t(131072), int64_t(70368744177664)),
    567                int64_t(-9223372036854775807 - 1)),
    568      "multiply that populates the sign bit produces minval");
    569  MOZ_RELEASE_ASSERT(TestEqual(WrappingMultiply(int64_t(9223372036854775807),
    570                                                int64_t(9223372036854775807)),
    571                               int64_t(1)),
    572                     "multiplying maxvals overflows all the way to 1");
    573 }
    574 
    575 static void TestWrappingMultiply() {
    576  TestWrappingMultiply8();
    577  TestWrappingMultiply16();
    578  TestWrappingMultiply32();
    579  TestWrappingMultiply64();
    580 }
    581 
    582 int main() {
    583  TestWrappingAdd();
    584  TestWrappingSubtract();
    585  TestWrappingMultiply();
    586  return 0;
    587 }