Home | History | Annotate | Download | only in interpreter
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "safe_math.h"
     18 
     19 #include <limits>
     20 
     21 #include "gtest/gtest.h"
     22 
     23 namespace art {
     24 namespace interpreter {
     25 
     26 TEST(SafeMath, Add) {
     27   // Adding 1 overflows 0x7ff... to 0x800... aka max and min.
     28   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max(), 1),
     29             std::numeric_limits<int32_t>::min());
     30   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max(), 1),
     31             std::numeric_limits<int64_t>::min());
     32 
     33   // Vanilla arithmetic should work too.
     34   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max() - 1, 1),
     35             std::numeric_limits<int32_t>::max());
     36   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max() - 1, 1),
     37             std::numeric_limits<int64_t>::max());
     38 
     39   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::min() + 1, -1),
     40             std::numeric_limits<int32_t>::min());
     41   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::min() + 1, -1),
     42             std::numeric_limits<int64_t>::min());
     43 
     44   EXPECT_EQ(SafeAdd(int32_t(-1), -1), -2);
     45   EXPECT_EQ(SafeAdd(int64_t(-1), -1), -2);
     46 
     47   EXPECT_EQ(SafeAdd(int32_t(1), 1), 2);
     48   EXPECT_EQ(SafeAdd(int64_t(1), 1), 2);
     49 
     50   EXPECT_EQ(SafeAdd(int32_t(-1), 1), 0);
     51   EXPECT_EQ(SafeAdd(int64_t(-1), 1), 0);
     52 
     53   EXPECT_EQ(SafeAdd(int32_t(1), -1), 0);
     54   EXPECT_EQ(SafeAdd(int64_t(1), -1), 0);
     55 
     56   // Test sign extension of smaller operand sizes.
     57   EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
     58   EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
     59 }
     60 
     61 TEST(SafeMath, Sub) {
     62   // Subtracting 1 underflows 0x800... to 0x7ff... aka min and max.
     63   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min(), 1),
     64             std::numeric_limits<int32_t>::max());
     65   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min(), 1),
     66             std::numeric_limits<int64_t>::max());
     67 
     68   // Vanilla arithmetic should work too.
     69   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::max() - 1, -1),
     70             std::numeric_limits<int32_t>::max());
     71   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::max() - 1, -1),
     72             std::numeric_limits<int64_t>::max());
     73 
     74   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min() + 1, 1),
     75             std::numeric_limits<int32_t>::min());
     76   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min() + 1, 1),
     77             std::numeric_limits<int64_t>::min());
     78 
     79   EXPECT_EQ(SafeSub(int32_t(-1), -1), 0);
     80   EXPECT_EQ(SafeSub(int64_t(-1), -1), 0);
     81 
     82   EXPECT_EQ(SafeSub(int32_t(1), 1), 0);
     83   EXPECT_EQ(SafeSub(int64_t(1), 1), 0);
     84 
     85   EXPECT_EQ(SafeSub(int32_t(-1), 1), -2);
     86   EXPECT_EQ(SafeSub(int64_t(-1), 1), -2);
     87 
     88   EXPECT_EQ(SafeSub(int32_t(1), -1), 2);
     89   EXPECT_EQ(SafeSub(int64_t(1), -1), 2);
     90 
     91   // Test sign extension of smaller operand sizes.
     92   EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
     93   EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
     94 }
     95 
     96 TEST(SafeMath, Mul) {
     97   // Multiplying by 2 overflows 0x7ff...f to 0xfff...e aka max and -2.
     98   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max(), 2),
     99             -2);
    100   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max(), 2),
    101             -2);
    102 
    103   // Vanilla arithmetic should work too.
    104   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max() / 2, 2),
    105             std::numeric_limits<int32_t>::max() - 1);  // -1 as LSB is lost by division.
    106   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max() / 2, 2),
    107             std::numeric_limits<int64_t>::max() - 1);  // -1 as LSB is lost by division.
    108 
    109   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::min() / 2, 2),
    110             std::numeric_limits<int32_t>::min());
    111   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::min() / 2, 2),
    112             std::numeric_limits<int64_t>::min());
    113 
    114   EXPECT_EQ(SafeMul(int32_t(-1), -1), 1);
    115   EXPECT_EQ(SafeMul(int64_t(-1), -1), 1);
    116 
    117   EXPECT_EQ(SafeMul(int32_t(1), 1), 1);
    118   EXPECT_EQ(SafeMul(int64_t(1), 1), 1);
    119 
    120   EXPECT_EQ(SafeMul(int32_t(-1), 1), -1);
    121   EXPECT_EQ(SafeMul(int64_t(-1), 1), -1);
    122 
    123   EXPECT_EQ(SafeMul(int32_t(1), -1), -1);
    124   EXPECT_EQ(SafeMul(int64_t(1), -1), -1);
    125 
    126   // Test sign extension of smaller operand sizes.
    127   EXPECT_EQ(SafeMul(int32_t(1), int8_t(-1)), -1);
    128   EXPECT_EQ(SafeMul(int64_t(1), int8_t(-1)), -1);
    129 }
    130 
    131 }  // namespace interpreter
    132 }  // namespace art
    133