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