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 
TEST(SafeMath,Add)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 
TEST(SafeMath,Sub)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 
TEST(SafeMath,Mul)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