1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <gtest/gtest.h>
10 #include "base/safe_numerics.h"
15 // This is far (far, far) too slow to run normally, but if you're refactoring
16 // it might be useful.
17 // #define RUN_EXHAUSTIVE_TEST
19 #ifdef RUN_EXHAUSTIVE_TEST
21 template <class From
, class To
> void ExhaustiveCheckFromTo() {
23 From i
= std::numeric_limits
<From
>::min();
25 std::ostringstream str_from
, str_to
;
27 To to
= static_cast<To
>(i
);
29 bool strings_equal
= str_from
.str() == str_to
.str();
30 EXPECT_EQ(IsValidNumericCast
<To
>(i
), strings_equal
);
31 fprintf(stderr
, "\r%s vs %s\x1B[K",
32 str_from
.str().c_str(), str_to
.str().c_str());
34 // If we wrap, then we've tested everything.
35 if (i
== std::numeric_limits
<From
>::min())
40 template <class From
> void ExhaustiveCheckFrom() {
41 ExhaustiveCheckFromTo
<From
, short>();
42 ExhaustiveCheckFromTo
<From
, unsigned short>();
43 ExhaustiveCheckFromTo
<From
, int>();
44 ExhaustiveCheckFromTo
<From
, unsigned int>();
45 ExhaustiveCheckFromTo
<From
, long long>();
46 ExhaustiveCheckFromTo
<From
, unsigned long long>();
47 ExhaustiveCheckFromTo
<From
, size_t>();
48 fprintf(stderr
, "\n");
54 TEST(SafeNumerics
, NumericCast
) {
55 int small_positive
= 1;
56 int small_negative
= -1;
57 int large_positive
= INT_MAX
;
58 int large_negative
= INT_MIN
;
59 size_t size_t_small
= 1;
60 size_t size_t_large
= UINT_MAX
;
62 // Narrow signed destination.
63 EXPECT_TRUE(IsValidNumericCast
<signed char>(small_positive
));
64 EXPECT_TRUE(IsValidNumericCast
<signed char>(small_negative
));
65 EXPECT_FALSE(IsValidNumericCast
<signed char>(large_positive
));
66 EXPECT_FALSE(IsValidNumericCast
<signed char>(large_negative
));
67 EXPECT_TRUE(IsValidNumericCast
<signed short>(small_positive
));
68 EXPECT_TRUE(IsValidNumericCast
<signed short>(small_negative
));
70 // Narrow unsigned destination.
71 EXPECT_TRUE(IsValidNumericCast
<unsigned char>(small_positive
));
72 EXPECT_FALSE(IsValidNumericCast
<unsigned char>(small_negative
));
73 EXPECT_FALSE(IsValidNumericCast
<unsigned char>(large_positive
));
74 EXPECT_FALSE(IsValidNumericCast
<unsigned char>(large_negative
));
75 EXPECT_FALSE(IsValidNumericCast
<unsigned short>(small_negative
));
76 EXPECT_FALSE(IsValidNumericCast
<unsigned short>(large_negative
));
78 // Same width signed destination.
79 EXPECT_TRUE(IsValidNumericCast
<signed int>(small_positive
));
80 EXPECT_TRUE(IsValidNumericCast
<signed int>(small_negative
));
81 EXPECT_TRUE(IsValidNumericCast
<signed int>(large_positive
));
82 EXPECT_TRUE(IsValidNumericCast
<signed int>(large_negative
));
84 // Same width unsigned destination.
85 EXPECT_TRUE(IsValidNumericCast
<unsigned int>(small_positive
));
86 EXPECT_FALSE(IsValidNumericCast
<unsigned int>(small_negative
));
87 EXPECT_TRUE(IsValidNumericCast
<unsigned int>(large_positive
));
88 EXPECT_FALSE(IsValidNumericCast
<unsigned int>(large_negative
));
90 // Wider signed destination.
91 EXPECT_TRUE(IsValidNumericCast
<long long>(small_positive
));
92 EXPECT_TRUE(IsValidNumericCast
<long long>(large_negative
));
93 EXPECT_TRUE(IsValidNumericCast
<long long>(small_positive
));
94 EXPECT_TRUE(IsValidNumericCast
<long long>(large_negative
));
96 // Wider unsigned destination.
97 EXPECT_TRUE(IsValidNumericCast
<unsigned long long>(small_positive
));
98 EXPECT_FALSE(IsValidNumericCast
<unsigned long long>(small_negative
));
99 EXPECT_TRUE(IsValidNumericCast
<unsigned long long>(large_positive
));
100 EXPECT_FALSE(IsValidNumericCast
<unsigned long long>(large_negative
));
102 // Negative to size_t.
103 EXPECT_FALSE(IsValidNumericCast
<size_t>(small_negative
));
104 EXPECT_FALSE(IsValidNumericCast
<size_t>(large_negative
));
108 EXPECT_TRUE(IsValidNumericCast
<signed char>(size_t_small
));
109 EXPECT_TRUE(IsValidNumericCast
<unsigned char>(size_t_small
));
110 EXPECT_TRUE(IsValidNumericCast
<short>(size_t_small
));
111 EXPECT_TRUE(IsValidNumericCast
<unsigned short>(size_t_small
));
112 EXPECT_TRUE(IsValidNumericCast
<int>(size_t_small
));
113 EXPECT_TRUE(IsValidNumericCast
<unsigned int>(size_t_small
));
114 EXPECT_TRUE(IsValidNumericCast
<long long>(size_t_small
));
115 EXPECT_TRUE(IsValidNumericCast
<unsigned long long>(size_t_small
));
118 EXPECT_FALSE(IsValidNumericCast
<signed char>(size_t_large
));
119 EXPECT_FALSE(IsValidNumericCast
<unsigned char>(size_t_large
));
120 EXPECT_FALSE(IsValidNumericCast
<short>(size_t_large
));
121 EXPECT_FALSE(IsValidNumericCast
<unsigned short>(size_t_large
));
122 EXPECT_FALSE(IsValidNumericCast
<int>(size_t_large
));
123 EXPECT_TRUE(IsValidNumericCast
<unsigned int>(size_t_large
));
124 EXPECT_TRUE(IsValidNumericCast
<long long>(size_t_large
));
125 EXPECT_TRUE(IsValidNumericCast
<unsigned long long>(size_t_large
));
127 // Various edge cases.
128 EXPECT_TRUE(IsValidNumericCast
<int>(static_cast<short>(SHRT_MIN
)));
130 IsValidNumericCast
<unsigned short>(static_cast<short>(SHRT_MIN
)));
131 EXPECT_FALSE(IsValidNumericCast
<unsigned short>(SHRT_MIN
));
133 // Confirm that checked_numeric_cast<> actually compiles.
135 unsigned int checked_size
=
136 base::checked_numeric_cast
<unsigned int>(v
.size());
137 EXPECT_EQ(0u, checked_size
);
139 #ifdef RUN_EXHAUSTIVE_TEST
140 ExhaustiveCheckFrom
<short>();
141 ExhaustiveCheckFrom
<unsigned short>();
142 ExhaustiveCheckFrom
<int>();
143 ExhaustiveCheckFrom
<unsigned int>();
144 ExhaustiveCheckFrom
<long long>();
145 ExhaustiveCheckFrom
<unsigned long long>();
146 ExhaustiveCheckFrom
<size_t>();
150 } // namespace internal