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