1/*
2 * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include <wtf/CheckedArithmetic.h>
28
29namespace TestWebKitAPI {
30
31class OverflowCrashLogger {
32protected:
33 void overflowed()
34 {
35 m_overflowCount++;
36 }
37
38 void clearOverflow()
39 {
40 m_overflowCount = 0;
41 }
42
43 static void crash()
44 {
45 s_didCrash = true;
46 }
47
48public:
49 void reset()
50 {
51 m_overflowCount = 0;
52 s_didCrash = false;
53 }
54
55 bool hasOverflowed() const { return m_overflowCount > 0; }
56 int overflowCount() const { return m_overflowCount; }
57
58 bool didCrash() const { return s_didCrash; }
59
60private:
61 int m_overflowCount { 0 };
62 static bool s_didCrash;
63};
64
65bool OverflowCrashLogger::s_didCrash = false;
66
67template <typename type>
68static void resetOverflow(Checked<type, OverflowCrashLogger>& value)
69{
70 value.reset();
71 value = 100;
72 value *= std::numeric_limits<type>::max();
73}
74
75#define CheckedArithmeticTest(type, Coercer, MixedSignednessTester) \
76 TEST(WTF, Checked_##type) \
77 { \
78 typedef Coercer<type> CoercerType; \
79 typedef MixedSignednessTester<type, CoercerType> MixedSignednessTesterType; \
80 CheckedArithmeticTester<type, CoercerType, MixedSignednessTesterType>::run(); \
81 }
82
83#define coerceLiteral(x) Coercer::coerce(x)
84
85template <typename type, typename Coercer, typename MixedSignednessTester>
86class CheckedArithmeticTester {
87public:
88 static void run()
89 {
90 Checked<type, RecordOverflow> value;
91 EXPECT_EQ(coerceLiteral(0), value.unsafeGet());
92 EXPECT_EQ(std::numeric_limits<type>::max(), (value + std::numeric_limits<type>::max()).unsafeGet());
93 EXPECT_EQ(std::numeric_limits<type>::max(), (std::numeric_limits<type>::max() + value).unsafeGet());
94 EXPECT_EQ(std::numeric_limits<type>::min(), (value + std::numeric_limits<type>::min()).unsafeGet());
95 EXPECT_EQ(std::numeric_limits<type>::min(), (std::numeric_limits<type>::min() + value).unsafeGet());
96
97 EXPECT_EQ(coerceLiteral(0), (value * coerceLiteral(0)).unsafeGet());
98 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) * value).unsafeGet());
99 EXPECT_EQ(coerceLiteral(0), (value * value).unsafeGet());
100 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(0)).unsafeGet());
101 EXPECT_EQ(coerceLiteral(0), (coerceLiteral(0) - value).unsafeGet());
102 EXPECT_EQ(coerceLiteral(0), (value - value).unsafeGet());
103 EXPECT_EQ(coerceLiteral(0), (value++).unsafeGet());
104 EXPECT_EQ(coerceLiteral(1), (value--).unsafeGet());
105 EXPECT_EQ(coerceLiteral(1), (++value).unsafeGet());
106 EXPECT_EQ(coerceLiteral(0), (--value).unsafeGet());
107 EXPECT_EQ(coerceLiteral(10), (value += coerceLiteral(10)).unsafeGet());
108 EXPECT_EQ(coerceLiteral(10), value.unsafeGet());
109 EXPECT_EQ(coerceLiteral(100), (value *= coerceLiteral(10)).unsafeGet());
110 EXPECT_EQ(coerceLiteral(100), value.unsafeGet());
111 EXPECT_EQ(coerceLiteral(0), (value -= coerceLiteral(100)).unsafeGet());
112 EXPECT_EQ(coerceLiteral(0), value.unsafeGet());
113 value = 10;
114 EXPECT_EQ(coerceLiteral(10), value.unsafeGet());
115 EXPECT_EQ(coerceLiteral(0), (value - coerceLiteral(10)).unsafeGet());
116 EXPECT_EQ(coerceLiteral(10), value.unsafeGet());
117
118 value = std::numeric_limits<type>::min();
119 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - coerceLiteral(1))).hasOverflowed());
120 EXPECT_EQ(true, !((value--).hasOverflowed()));
121 EXPECT_EQ(true, value.hasOverflowed());
122 value = std::numeric_limits<type>::max();
123 EXPECT_EQ(true, !value.hasOverflowed());
124 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + coerceLiteral(1))).hasOverflowed());
125 EXPECT_EQ(true, !(value++).hasOverflowed());
126 EXPECT_EQ(true, value.hasOverflowed());
127 value = std::numeric_limits<type>::max();
128 EXPECT_EQ(true, (value += coerceLiteral(1)).hasOverflowed());
129 EXPECT_EQ(true, value.hasOverflowed());
130
131 value = 10;
132 type _value = 0;
133 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(0)).safeGet(_value));
134 _value = 0;
135 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(0) * value).safeGet(_value));
136 _value = 0;
137 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
138 _value = 0;
139 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value));
140 value = 0;
141 _value = 0;
142 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
143 _value = 0;
144 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value));
145 value = 1;
146 _value = 0;
147 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
148 _value = 0;
149 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * value).safeGet(_value));
150 _value = 0;
151 value = 0;
152 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
153 _value = 0;
154 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)0).safeGet(_value));
155 _value = 0;
156 value = 1;
157 EXPECT_EQ(true, CheckedState::DidNotOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
158 _value = 0;
159 EXPECT_EQ(true, CheckedState::DidNotOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)1).safeGet(_value));
160 _value = 0;
161 value = 2;
162 EXPECT_EQ(true, CheckedState::DidOverflow == (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).safeGet(_value));
163 _value = 0;
164 EXPECT_EQ(true, CheckedState::DidOverflow == (Checked<type, RecordOverflow>(std::numeric_limits<type>::max()) * (type)2).safeGet(_value));
165 value = 10;
166 EXPECT_EQ(true, (value * Checked<type, RecordOverflow>(std::numeric_limits<type>::max())).hasOverflowed());
167
168
169 Checked<type, OverflowCrashLogger> nvalue; // to hold a not overflowed value.
170 Checked<type, OverflowCrashLogger> ovalue; // to hold an overflowed value.
171
172 bool unused;
173 UNUSED_PARAM(unused);
174
175 _value = 75;
176 type _largeValue = 100;
177 type _smallValue = 50;
178
179 value = _smallValue;
180 nvalue = _value;
181 ovalue = _value;
182
183 // Make sure the OverflowCrashLogger is working as expected.
184 EXPECT_EQ(false, (ovalue.hasOverflowed()));
185 EXPECT_EQ(true, (resetOverflow(ovalue), ovalue.hasOverflowed()));
186 EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
187 EXPECT_EQ(true, (unused = (ovalue == ovalue), ovalue.didCrash()));
188 EXPECT_EQ(false, (resetOverflow(ovalue), ovalue.didCrash()));
189
190 EXPECT_EQ(false, nvalue.hasOverflowed());
191 EXPECT_EQ(false, nvalue.didCrash());
192
193 // Test operator== that should not overflow nor crash.
194 EXPECT_EQ(true, (nvalue == nvalue));
195 EXPECT_EQ(true, (nvalue == Checked<type, OverflowCrashLogger>(_value)));
196 EXPECT_EQ(false, (nvalue == value));
197 EXPECT_EQ(true, (nvalue == _value));
198 EXPECT_EQ(false, (nvalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
199 EXPECT_EQ(false, (nvalue == std::numeric_limits<type>::max()));
200
201 EXPECT_EQ(false, nvalue.hasOverflowed());
202 EXPECT_EQ(false, nvalue.didCrash());
203
204 // Test operator!= that should not overflow nor crash.
205 EXPECT_EQ(false, (nvalue != nvalue));
206 EXPECT_EQ(false, (nvalue != Checked<type, OverflowCrashLogger>(_value)));
207 EXPECT_EQ(true, (nvalue != value));
208 EXPECT_EQ(false, (nvalue != _value));
209 EXPECT_EQ(true, (nvalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
210 EXPECT_EQ(true, (nvalue != std::numeric_limits<type>::max()));
211
212 EXPECT_EQ(false, nvalue.hasOverflowed());
213 EXPECT_EQ(false, nvalue.didCrash());
214
215 // Test operator< that should not overflow nor crash.
216 EXPECT_EQ(false, (nvalue < nvalue));
217 EXPECT_EQ(false, (nvalue < value));
218 EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(_largeValue)));
219 EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_value)));
220 EXPECT_EQ(false, (nvalue < Checked<type, OverflowCrashLogger>(_smallValue)));
221 EXPECT_EQ(true, (nvalue < _largeValue));
222 EXPECT_EQ(false, (nvalue < _value));
223 EXPECT_EQ(false, (nvalue < _smallValue));
224 EXPECT_EQ(true, (nvalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
225 EXPECT_EQ(true, (nvalue < std::numeric_limits<type>::max()));
226
227 EXPECT_EQ(false, nvalue.hasOverflowed());
228 EXPECT_EQ(false, nvalue.didCrash());
229
230 // Test operator<= that should not overflow nor crash.
231 EXPECT_EQ(true, (nvalue <= nvalue));
232 EXPECT_EQ(false, (nvalue <= value));
233 EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_largeValue)));
234 EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(_value)));
235 EXPECT_EQ(false, (nvalue <= Checked<type, OverflowCrashLogger>(_smallValue)));
236 EXPECT_EQ(true, (nvalue <= _largeValue));
237 EXPECT_EQ(true, (nvalue <= _value));
238 EXPECT_EQ(false, (nvalue <= _smallValue));
239 EXPECT_EQ(true, (nvalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
240 EXPECT_EQ(true, (nvalue <= std::numeric_limits<type>::max()));
241
242 EXPECT_EQ(false, nvalue.hasOverflowed());
243 EXPECT_EQ(false, nvalue.didCrash());
244
245 // Test operator> that should not overflow nor crash.
246 EXPECT_EQ(false, (nvalue > nvalue));
247 EXPECT_EQ(true, (nvalue > value));
248 EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_largeValue)));
249 EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(_value)));
250 EXPECT_EQ(true, (nvalue > Checked<type, OverflowCrashLogger>(_smallValue)));
251 EXPECT_EQ(false, (nvalue > _largeValue));
252 EXPECT_EQ(false, (nvalue > _value));
253 EXPECT_EQ(true, (nvalue > _smallValue));
254 EXPECT_EQ(false, (nvalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
255 EXPECT_EQ(false, (nvalue > std::numeric_limits<type>::max()));
256
257 EXPECT_EQ(false, nvalue.hasOverflowed());
258 EXPECT_EQ(false, nvalue.didCrash());
259
260 // Test operator>= that should not overflow nor crash.
261 EXPECT_EQ(true, (nvalue >= nvalue));
262 EXPECT_EQ(true, (nvalue >= value));
263 EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(_largeValue)));
264 EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_value)));
265 EXPECT_EQ(true, (nvalue >= Checked<type, OverflowCrashLogger>(_smallValue)));
266 EXPECT_EQ(false, (nvalue >= _largeValue));
267 EXPECT_EQ(true, (nvalue >= _value));
268 EXPECT_EQ(true, (nvalue >= _smallValue));
269 EXPECT_EQ(false, (nvalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())));
270 EXPECT_EQ(false, (nvalue >= std::numeric_limits<type>::max()));
271
272 EXPECT_EQ(false, nvalue.hasOverflowed());
273 EXPECT_EQ(false, nvalue.didCrash());
274
275 // Test operator== with an overflowed value.
276 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == ovalue), ovalue.didCrash()));
277 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
278 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == value), ovalue.didCrash()));
279 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value), ovalue.didCrash()));
280 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
281 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
282 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == std::numeric_limits<type>::max()), ovalue.didCrash()));
283 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue == nvalue), ovalue.didCrash()));
284 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue == ovalue), ovalue.didCrash()));
285
286 EXPECT_EQ(false, nvalue.hasOverflowed());
287
288 // Test operator!= with an overflowed value.
289 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != ovalue), ovalue.didCrash()));
290 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
291 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != value), ovalue.didCrash()));
292 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value), ovalue.didCrash()));
293 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != _value * std::numeric_limits<type>::max()), ovalue.didCrash()));
294 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
295 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != std::numeric_limits<type>::max()), ovalue.didCrash()));
296 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue != nvalue), ovalue.didCrash()));
297 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue != ovalue), ovalue.didCrash()));
298
299 EXPECT_EQ(false, nvalue.hasOverflowed());
300
301 // Test operator< with an overflowed value.
302 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < ovalue), ovalue.didCrash()));
303 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < value), ovalue.didCrash()));
304 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
305 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
306 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
307 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _largeValue), ovalue.didCrash()));
308 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _value), ovalue.didCrash()));
309 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < _smallValue), ovalue.didCrash()));
310 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
311 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < std::numeric_limits<type>::max()), ovalue.didCrash()));
312 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue < nvalue), ovalue.didCrash()));
313 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue < ovalue), ovalue.didCrash()));
314
315 EXPECT_EQ(false, nvalue.hasOverflowed());
316
317 // Test operator<= with an overflowed value.
318 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= ovalue), ovalue.didCrash()));
319 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= value), ovalue.didCrash()));
320 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
321 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
322 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
323 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _largeValue), ovalue.didCrash()));
324 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _value), ovalue.didCrash()));
325 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= _smallValue), ovalue.didCrash()));
326 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
327 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= std::numeric_limits<type>::max()), ovalue.didCrash()));
328 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue <= nvalue), ovalue.didCrash()));
329 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue <= ovalue), ovalue.didCrash()));
330
331 EXPECT_EQ(false, nvalue.hasOverflowed());
332
333 // Test operator> with an overflowed value.
334 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > ovalue), ovalue.didCrash()));
335 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > value), ovalue.didCrash()));
336 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
337 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
338 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
339 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _largeValue), ovalue.didCrash()));
340 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _value), ovalue.didCrash()));
341 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > _smallValue), ovalue.didCrash()));
342 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
343 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > std::numeric_limits<type>::max()), ovalue.didCrash()));
344 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue > nvalue), ovalue.didCrash()));
345 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue > ovalue), ovalue.didCrash()));
346
347 EXPECT_EQ(false, nvalue.hasOverflowed());
348
349 // Test operator>= with an overflowed value.
350 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= ovalue), ovalue.didCrash()));
351 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= value), ovalue.didCrash()));
352 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_largeValue)), ovalue.didCrash()));
353 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_value)), ovalue.didCrash()));
354 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(_smallValue)), ovalue.didCrash()));
355 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _largeValue), ovalue.didCrash()));
356 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _value), ovalue.didCrash()));
357 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= _smallValue), ovalue.didCrash()));
358 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= Checked<type, OverflowCrashLogger>(std::numeric_limits<type>::max())), ovalue.didCrash()));
359 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= std::numeric_limits<type>::max()), ovalue.didCrash()));
360 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (ovalue >= nvalue), ovalue.didCrash()));
361 EXPECT_EQ(true, (resetOverflow(ovalue), unused = (nvalue >= ovalue), ovalue.didCrash()));
362
363 EXPECT_EQ(false, nvalue.hasOverflowed());
364
365 MixedSignednessTester::run();
366 }
367};
368
369template <typename type, typename Coercer>
370class AllowMixedSignednessTest {
371public:
372 static void run()
373 {
374 Checked<type, RecordOverflow> value;
375 value = 10;
376
377 EXPECT_EQ(coerceLiteral(0), (value + -10).unsafeGet());
378 EXPECT_EQ(0U, (value - 10U).unsafeGet());
379 EXPECT_EQ(coerceLiteral(0), (-10 + value).unsafeGet());
380 EXPECT_EQ(0U, (10U - value).unsafeGet());
381 value = std::numeric_limits<type>::min();
382 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value - 1)).hasOverflowed());
383 EXPECT_EQ(true, !(value--).hasOverflowed());
384 EXPECT_EQ(true, value.hasOverflowed());
385 value = std::numeric_limits<type>::max();
386 EXPECT_EQ(true, !value.hasOverflowed());
387 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1)).hasOverflowed());
388 EXPECT_EQ(true, !(value++).hasOverflowed());
389 EXPECT_EQ(true, value.hasOverflowed());
390 value = std::numeric_limits<type>::max();
391 EXPECT_EQ(true, (value += 1).hasOverflowed());
392 EXPECT_EQ(true, value.hasOverflowed());
393 value = std::numeric_limits<type>::min();
394 EXPECT_EQ(true, (value - 1U).hasOverflowed());
395 EXPECT_EQ(true, !(value--).hasOverflowed());
396 EXPECT_EQ(true, value.hasOverflowed());
397 value = std::numeric_limits<type>::max();
398 EXPECT_EQ(true, !value.hasOverflowed());
399 EXPECT_EQ(true, (Checked<type, RecordOverflow>(value + 1U)).hasOverflowed());
400 EXPECT_EQ(true, !(value++).hasOverflowed());
401 EXPECT_EQ(true, value.hasOverflowed());
402 value = std::numeric_limits<type>::max();
403 EXPECT_EQ(true, (value += 1U).hasOverflowed());
404 EXPECT_EQ(true, value.hasOverflowed());
405 }
406};
407
408template <typename type, typename Coercer>
409class IgnoreMixedSignednessTest {
410public:
411 static void run() { }
412};
413
414template <typename type> class CoerceLiteralToUnsigned {
415public:
416 static unsigned coerce(type x) { return static_cast<unsigned>(x); }
417};
418
419template <typename type> class CoerceLiteralNop {
420public:
421 static type coerce(type x) { return x; }
422};
423
424CheckedArithmeticTest(int8_t, CoerceLiteralNop, IgnoreMixedSignednessTest)
425CheckedArithmeticTest(int16_t, CoerceLiteralNop, IgnoreMixedSignednessTest)
426CheckedArithmeticTest(int32_t, CoerceLiteralNop, AllowMixedSignednessTest)
427CheckedArithmeticTest(uint32_t, CoerceLiteralToUnsigned, AllowMixedSignednessTest)
428CheckedArithmeticTest(int64_t, CoerceLiteralNop, IgnoreMixedSignednessTest)
429CheckedArithmeticTest(uint64_t, CoerceLiteralToUnsigned, IgnoreMixedSignednessTest)
430
431TEST(CheckedArithmeticTest, IsInBounds)
432{
433 // bigger precision, signed, signed
434 EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<int16_t>::max()));
435 EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<int16_t>::min()));
436
437 // bigger precision, unsigned, signed
438 EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int32_t>::max()));
439 EXPECT_FALSE(WTF::isInBounds<uint32_t>(std::numeric_limits<int16_t>::min()));
440
441 EXPECT_FALSE(WTF::isInBounds<uint32_t>((int32_t)-1));
442 EXPECT_FALSE(WTF::isInBounds<uint16_t>((int32_t)-1));
443 EXPECT_FALSE(WTF::isInBounds<unsigned long>((int)-1));
444
445 EXPECT_TRUE(WTF::isInBounds<uint32_t>((int32_t)1));
446 EXPECT_TRUE(WTF::isInBounds<uint32_t>((int16_t)1));
447 EXPECT_TRUE(WTF::isInBounds<unsigned>((int)1));
448
449 EXPECT_TRUE(WTF::isInBounds<uint32_t>((int32_t)0));
450 EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)0));
451 EXPECT_TRUE(WTF::isInBounds<uint32_t>((int16_t)0));
452 EXPECT_TRUE(WTF::isInBounds<unsigned>((int)0));
453
454 EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int32_t>::max()));
455 EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<int16_t>::max()));
456 EXPECT_TRUE(WTF::isInBounds<unsigned>(std::numeric_limits<int>::max()));
457
458 // bigger precision, signed, unsigned
459 EXPECT_TRUE(WTF::isInBounds<int32_t>(std::numeric_limits<uint16_t>::max()));
460 EXPECT_FALSE(WTF::isInBounds<int32_t>(std::numeric_limits<uint32_t>::max()));
461 EXPECT_TRUE(WTF::isInBounds<int32_t>((uint32_t)0));
462
463 // bigger precision, unsigned, unsigned
464 EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<uint16_t>::max()));
465 EXPECT_TRUE(WTF::isInBounds<uint32_t>(std::numeric_limits<uint16_t>::min()));
466
467 // lower precision, signed signed
468 EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<int32_t>::max()));
469 EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<int32_t>::min()));
470 EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)-1));
471 EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)0));
472 EXPECT_TRUE(WTF::isInBounds<int16_t>((int32_t)1));
473 // lower precision, unsigned, signed
474 EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<int32_t>::max()));
475 EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<int32_t>::min()));
476 EXPECT_FALSE(WTF::isInBounds<uint16_t>((int32_t)-1));
477 EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)0));
478 EXPECT_TRUE(WTF::isInBounds<uint16_t>((int32_t)1));
479 // lower precision, signed, unsigned
480 EXPECT_FALSE(WTF::isInBounds<int16_t>(std::numeric_limits<uint32_t>::max()));
481 EXPECT_TRUE(WTF::isInBounds<int16_t>((uint32_t)0));
482 EXPECT_TRUE(WTF::isInBounds<int16_t>((uint32_t)1));
483 // lower precision, unsigned, unsigned
484 EXPECT_FALSE(WTF::isInBounds<uint16_t>(std::numeric_limits<uint32_t>::max()));
485 EXPECT_TRUE(WTF::isInBounds<uint16_t>((uint32_t)0));
486 EXPECT_TRUE(WTF::isInBounds<uint16_t>((uint32_t)1));
487}
488
489} // namespace TestWebKitAPI
490