OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <limits> | |
12 | |
13 #include "webrtc/base/safe_compare.h" | |
14 #include "webrtc/test/gtest.h" | |
15 | |
16 namespace rtc { | |
17 | |
18 namespace { | |
19 | |
20 constexpr std::uintmax_t umax = std::numeric_limits<std::uintmax_t>::max(); | |
21 constexpr std::intmax_t imin = std::numeric_limits<std::intmax_t>::min(); | |
22 constexpr std::intmax_t m1 = -1; | |
23 | |
24 // m1 and umax have the same representation because we use 2's complement | |
25 // arithmetic, so naive casting will confuse them. | |
26 static_assert(static_cast<std::uintmax_t>(m1) == umax, ""); | |
27 static_assert(m1 == static_cast<std::intmax_t>(umax), ""); | |
28 | |
29 static const std::pair<int, int> p1(1, 1); | |
30 static const std::pair<int, int> p2(1, 2); | |
31 | |
32 } // namespace | |
33 | |
34 // clang-format off | |
35 | |
36 // These functions aren't used in the tests, but it's useful to look at the | |
37 // compiler output for them, and verify that (1) the same-signedness *Safe | |
38 // functions result in exactly the same code as their *Ref counterparts, and | |
39 // that (2) the mixed-signedness *Safe functions have just a few extra | |
40 // arithmetic and logic instructions (but no extra control flow instructions). | |
41 bool TestLessThanRef( int a, int b) { return a < b; } | |
42 bool TestLessThanRef( unsigned a, unsigned b) { return a < b; } | |
43 bool TestLessThanSafe( int a, int b) { return SafeLt(a, b); } | |
44 bool TestLessThanSafe(unsigned a, unsigned b) { return SafeLt(a, b); } | |
45 bool TestLessThanSafe(unsigned a, int b) { return SafeLt(a, b); } | |
46 bool TestLessThanSafe( int a, unsigned b) { return SafeLt(a, b); } | |
47 | |
48 // For these, we expect the *Ref and *Safe functions to result in identical | |
49 // code, except for the ones that compare a signed variable with an unsigned | |
50 // constant; in that case, the *Ref function does an unsigned comparison (fast | |
51 // but incorrect) and the *Safe function spends a few extra instructions on | |
52 // doing it right. | |
53 bool TestLessThan17Ref( int a) { return a < 17; } | |
54 bool TestLessThan17Ref( unsigned a) { return a < 17; } | |
55 bool TestLessThan17uRef( int a) { return static_cast<unsigned>(a) < 17u; } | |
56 bool TestLessThan17uRef( unsigned a) { return a < 17u; } | |
57 bool TestLessThan17Safe( int a) { return SafeLt(a, 17); } | |
58 bool TestLessThan17Safe( unsigned a) { return SafeLt(a, 17); } | |
59 bool TestLessThan17uSafe( int a) { return SafeLt(a, 17u); } | |
60 bool TestLessThan17uSafe(unsigned a) { return SafeLt(a, 17u); } | |
61 | |
62 // Cases where we can't convert to a larger signed type. | |
63 bool TestLessThanMax( intmax_t a, uintmax_t b) { return SafeLt(a, b); } | |
64 bool TestLessThanMax(uintmax_t a, intmax_t b) { return SafeLt(a, b); } | |
65 bool TestLessThanMax17u( intmax_t a) { return SafeLt(a, uintmax_t{17}); } | |
66 bool TestLessThanMax17( uintmax_t a) { return SafeLt(a, intmax_t{17}); } | |
67 | |
68 // Cases where the compiler should be able to compute the result at compile | |
69 // time. | |
70 bool TestLessThanConst1() { return SafeLt( -1, 1); } | |
71 bool TestLessThanConst2() { return SafeLt( m1, umax); } | |
72 bool TestLessThanConst3() { return SafeLt(umax, imin); } | |
73 bool TestLessThanConst4(unsigned a) { return SafeLt( a, -1); } | |
74 bool TestLessThanConst5(unsigned a) { return SafeLt(-1, a); } | |
75 bool TestLessThanConst6(unsigned a) { return SafeLt( a, a); } | |
76 | |
77 // clang-format on | |
78 | |
79 TEST(SafeCmpTest, Eq) { | |
80 static_assert(!SafeEq(-1, 2), ""); | |
81 static_assert(!SafeEq(-1, 2u), ""); | |
82 static_assert(!SafeEq(2, -1), ""); | |
83 static_assert(!SafeEq(2u, -1), ""); | |
84 | |
85 static_assert(!SafeEq(1, 2), ""); | |
86 static_assert(!SafeEq(1, 2u), ""); | |
87 static_assert(!SafeEq(1u, 2), ""); | |
88 static_assert(!SafeEq(1u, 2u), ""); | |
89 static_assert(!SafeEq(2, 1), ""); | |
90 static_assert(!SafeEq(2, 1u), ""); | |
91 static_assert(!SafeEq(2u, 1), ""); | |
92 static_assert(!SafeEq(2u, 1u), ""); | |
93 | |
94 static_assert(SafeEq(2, 2), ""); | |
95 static_assert(SafeEq(2, 2u), ""); | |
96 static_assert(SafeEq(2u, 2), ""); | |
97 static_assert(SafeEq(2u, 2u), ""); | |
98 | |
99 static_assert(SafeEq(imin, imin), ""); | |
100 static_assert(!SafeEq(imin, umax), ""); | |
101 static_assert(!SafeEq(umax, imin), ""); | |
102 static_assert(SafeEq(umax, umax), ""); | |
103 | |
104 static_assert(SafeEq(m1, m1), ""); | |
105 static_assert(!SafeEq(m1, umax), ""); | |
106 static_assert(!SafeEq(umax, m1), ""); | |
107 static_assert(SafeEq(umax, umax), ""); | |
108 | |
109 static_assert(!SafeEq(1, 2), ""); | |
110 static_assert(!SafeEq(1, 2.0), ""); | |
111 static_assert(!SafeEq(1.0, 2), ""); | |
112 static_assert(!SafeEq(1.0, 2.0), ""); | |
113 static_assert(!SafeEq(2, 1), ""); | |
114 static_assert(!SafeEq(2, 1.0), ""); | |
115 static_assert(!SafeEq(2.0, 1), ""); | |
116 static_assert(!SafeEq(2.0, 1.0), ""); | |
117 | |
118 static_assert(SafeEq(2, 2), ""); | |
119 static_assert(SafeEq(2, 2.0), ""); | |
120 static_assert(SafeEq(2.0, 2), ""); | |
121 static_assert(SafeEq(2.0, 2.0), ""); | |
122 | |
123 EXPECT_TRUE(SafeEq(p1, p1)); | |
124 EXPECT_FALSE(SafeEq(p1, p2)); | |
125 EXPECT_FALSE(SafeEq(p2, p1)); | |
126 EXPECT_TRUE(SafeEq(p2, p2)); | |
127 } | |
128 | |
129 TEST(SafeCmpTest, Ne) { | |
130 static_assert(SafeNe(-1, 2), ""); | |
131 static_assert(SafeNe(-1, 2u), ""); | |
132 static_assert(SafeNe(2, -1), ""); | |
133 static_assert(SafeNe(2u, -1), ""); | |
134 | |
135 static_assert(SafeNe(1, 2), ""); | |
136 static_assert(SafeNe(1, 2u), ""); | |
137 static_assert(SafeNe(1u, 2), ""); | |
138 static_assert(SafeNe(1u, 2u), ""); | |
139 static_assert(SafeNe(2, 1), ""); | |
140 static_assert(SafeNe(2, 1u), ""); | |
141 static_assert(SafeNe(2u, 1), ""); | |
142 static_assert(SafeNe(2u, 1u), ""); | |
143 | |
144 static_assert(!SafeNe(2, 2), ""); | |
145 static_assert(!SafeNe(2, 2u), ""); | |
146 static_assert(!SafeNe(2u, 2), ""); | |
147 static_assert(!SafeNe(2u, 2u), ""); | |
148 | |
149 static_assert(!SafeNe(imin, imin), ""); | |
150 static_assert(SafeNe(imin, umax), ""); | |
151 static_assert(SafeNe(umax, imin), ""); | |
152 static_assert(!SafeNe(umax, umax), ""); | |
153 | |
154 static_assert(!SafeNe(m1, m1), ""); | |
155 static_assert(SafeNe(m1, umax), ""); | |
156 static_assert(SafeNe(umax, m1), ""); | |
157 static_assert(!SafeNe(umax, umax), ""); | |
158 | |
159 static_assert(SafeNe(1, 2), ""); | |
160 static_assert(SafeNe(1, 2.0), ""); | |
161 static_assert(SafeNe(1.0, 2), ""); | |
162 static_assert(SafeNe(1.0, 2.0), ""); | |
163 static_assert(SafeNe(2, 1), ""); | |
164 static_assert(SafeNe(2, 1.0), ""); | |
165 static_assert(SafeNe(2.0, 1), ""); | |
166 static_assert(SafeNe(2.0, 1.0), ""); | |
167 | |
168 static_assert(!SafeNe(2, 2), ""); | |
169 static_assert(!SafeNe(2, 2.0), ""); | |
170 static_assert(!SafeNe(2.0, 2), ""); | |
171 static_assert(!SafeNe(2.0, 2.0), ""); | |
172 | |
173 EXPECT_FALSE(SafeNe(p1, p1)); | |
174 EXPECT_TRUE(SafeNe(p1, p2)); | |
175 EXPECT_TRUE(SafeNe(p2, p1)); | |
176 EXPECT_FALSE(SafeNe(p2, p2)); | |
177 } | |
178 | |
179 TEST(SafeCmpTest, Lt) { | |
180 static_assert(SafeLt(-1, 2), ""); | |
181 static_assert(SafeLt(-1, 2u), ""); | |
182 static_assert(!SafeLt(2, -1), ""); | |
183 static_assert(!SafeLt(2u, -1), ""); | |
184 | |
185 static_assert(SafeLt(1, 2), ""); | |
186 static_assert(SafeLt(1, 2u), ""); | |
187 static_assert(SafeLt(1u, 2), ""); | |
188 static_assert(SafeLt(1u, 2u), ""); | |
189 static_assert(!SafeLt(2, 1), ""); | |
190 static_assert(!SafeLt(2, 1u), ""); | |
191 static_assert(!SafeLt(2u, 1), ""); | |
192 static_assert(!SafeLt(2u, 1u), ""); | |
193 | |
194 static_assert(!SafeLt(2, 2), ""); | |
195 static_assert(!SafeLt(2, 2u), ""); | |
196 static_assert(!SafeLt(2u, 2), ""); | |
197 static_assert(!SafeLt(2u, 2u), ""); | |
198 | |
199 static_assert(!SafeLt(imin, imin), ""); | |
200 static_assert(SafeLt(imin, umax), ""); | |
201 static_assert(!SafeLt(umax, imin), ""); | |
202 static_assert(!SafeLt(umax, umax), ""); | |
203 | |
204 static_assert(!SafeLt(m1, m1), ""); | |
205 static_assert(SafeLt(m1, umax), ""); | |
206 static_assert(!SafeLt(umax, m1), ""); | |
207 static_assert(!SafeLt(umax, umax), ""); | |
208 | |
209 static_assert(SafeLt(1, 2), ""); | |
210 static_assert(SafeLt(1, 2.0), ""); | |
211 static_assert(SafeLt(1.0, 2), ""); | |
212 static_assert(SafeLt(1.0, 2.0), ""); | |
213 static_assert(!SafeLt(2, 1), ""); | |
214 static_assert(!SafeLt(2, 1.0), ""); | |
215 static_assert(!SafeLt(2.0, 1), ""); | |
216 static_assert(!SafeLt(2.0, 1.0), ""); | |
217 | |
218 static_assert(!SafeLt(2, 2), ""); | |
219 static_assert(!SafeLt(2, 2.0), ""); | |
220 static_assert(!SafeLt(2.0, 2), ""); | |
221 static_assert(!SafeLt(2.0, 2.0), ""); | |
222 | |
223 EXPECT_FALSE(SafeLt(p1, p1)); | |
224 EXPECT_TRUE(SafeLt(p1, p2)); | |
225 EXPECT_FALSE(SafeLt(p2, p1)); | |
226 EXPECT_FALSE(SafeLt(p2, p2)); | |
227 } | |
228 | |
229 TEST(SafeCmpTest, Le) { | |
230 static_assert(SafeLe(-1, 2), ""); | |
231 static_assert(SafeLe(-1, 2u), ""); | |
232 static_assert(!SafeLe(2, -1), ""); | |
233 static_assert(!SafeLe(2u, -1), ""); | |
234 | |
235 static_assert(SafeLe(1, 2), ""); | |
236 static_assert(SafeLe(1, 2u), ""); | |
237 static_assert(SafeLe(1u, 2), ""); | |
238 static_assert(SafeLe(1u, 2u), ""); | |
239 static_assert(!SafeLe(2, 1), ""); | |
240 static_assert(!SafeLe(2, 1u), ""); | |
241 static_assert(!SafeLe(2u, 1), ""); | |
242 static_assert(!SafeLe(2u, 1u), ""); | |
243 | |
244 static_assert(SafeLe(2, 2), ""); | |
245 static_assert(SafeLe(2, 2u), ""); | |
246 static_assert(SafeLe(2u, 2), ""); | |
247 static_assert(SafeLe(2u, 2u), ""); | |
248 | |
249 static_assert(SafeLe(imin, imin), ""); | |
250 static_assert(SafeLe(imin, umax), ""); | |
251 static_assert(!SafeLe(umax, imin), ""); | |
252 static_assert(SafeLe(umax, umax), ""); | |
253 | |
254 static_assert(SafeLe(m1, m1), ""); | |
255 static_assert(SafeLe(m1, umax), ""); | |
256 static_assert(!SafeLe(umax, m1), ""); | |
257 static_assert(SafeLe(umax, umax), ""); | |
258 | |
259 static_assert(SafeLe(1, 2), ""); | |
260 static_assert(SafeLe(1, 2.0), ""); | |
261 static_assert(SafeLe(1.0, 2), ""); | |
262 static_assert(SafeLe(1.0, 2.0), ""); | |
263 static_assert(!SafeLe(2, 1), ""); | |
264 static_assert(!SafeLe(2, 1.0), ""); | |
265 static_assert(!SafeLe(2.0, 1), ""); | |
266 static_assert(!SafeLe(2.0, 1.0), ""); | |
267 | |
268 static_assert(SafeLe(2, 2), ""); | |
269 static_assert(SafeLe(2, 2.0), ""); | |
270 static_assert(SafeLe(2.0, 2), ""); | |
271 static_assert(SafeLe(2.0, 2.0), ""); | |
272 | |
273 EXPECT_TRUE(SafeLe(p1, p1)); | |
274 EXPECT_TRUE(SafeLe(p1, p2)); | |
275 EXPECT_FALSE(SafeLe(p2, p1)); | |
276 EXPECT_TRUE(SafeLe(p2, p2)); | |
277 } | |
278 | |
279 TEST(SafeCmpTest, Gt) { | |
280 static_assert(!SafeGt(-1, 2), ""); | |
281 static_assert(!SafeGt(-1, 2u), ""); | |
282 static_assert(SafeGt(2, -1), ""); | |
283 static_assert(SafeGt(2u, -1), ""); | |
284 | |
285 static_assert(!SafeGt(1, 2), ""); | |
286 static_assert(!SafeGt(1, 2u), ""); | |
287 static_assert(!SafeGt(1u, 2), ""); | |
288 static_assert(!SafeGt(1u, 2u), ""); | |
289 static_assert(SafeGt(2, 1), ""); | |
290 static_assert(SafeGt(2, 1u), ""); | |
291 static_assert(SafeGt(2u, 1), ""); | |
292 static_assert(SafeGt(2u, 1u), ""); | |
293 | |
294 static_assert(!SafeGt(2, 2), ""); | |
295 static_assert(!SafeGt(2, 2u), ""); | |
296 static_assert(!SafeGt(2u, 2), ""); | |
297 static_assert(!SafeGt(2u, 2u), ""); | |
298 | |
299 static_assert(!SafeGt(imin, imin), ""); | |
300 static_assert(!SafeGt(imin, umax), ""); | |
301 static_assert(SafeGt(umax, imin), ""); | |
302 static_assert(!SafeGt(umax, umax), ""); | |
303 | |
304 static_assert(!SafeGt(m1, m1), ""); | |
305 static_assert(!SafeGt(m1, umax), ""); | |
306 static_assert(SafeGt(umax, m1), ""); | |
307 static_assert(!SafeGt(umax, umax), ""); | |
308 | |
309 static_assert(!SafeGt(1, 2), ""); | |
310 static_assert(!SafeGt(1, 2.0), ""); | |
311 static_assert(!SafeGt(1.0, 2), ""); | |
312 static_assert(!SafeGt(1.0, 2.0), ""); | |
313 static_assert(SafeGt(2, 1), ""); | |
314 static_assert(SafeGt(2, 1.0), ""); | |
315 static_assert(SafeGt(2.0, 1), ""); | |
316 static_assert(SafeGt(2.0, 1.0), ""); | |
317 | |
318 static_assert(!SafeGt(2, 2), ""); | |
319 static_assert(!SafeGt(2, 2.0), ""); | |
320 static_assert(!SafeGt(2.0, 2), ""); | |
321 static_assert(!SafeGt(2.0, 2.0), ""); | |
322 | |
323 EXPECT_FALSE(SafeGt(p1, p1)); | |
324 EXPECT_FALSE(SafeGt(p1, p2)); | |
325 EXPECT_TRUE(SafeGt(p2, p1)); | |
326 EXPECT_FALSE(SafeGt(p2, p2)); | |
327 } | |
328 | |
329 TEST(SafeCmpTest, Ge) { | |
330 static_assert(!SafeGe(-1, 2), ""); | |
331 static_assert(!SafeGe(-1, 2u), ""); | |
332 static_assert(SafeGe(2, -1), ""); | |
333 static_assert(SafeGe(2u, -1), ""); | |
334 | |
335 static_assert(!SafeGe(1, 2), ""); | |
336 static_assert(!SafeGe(1, 2u), ""); | |
337 static_assert(!SafeGe(1u, 2), ""); | |
338 static_assert(!SafeGe(1u, 2u), ""); | |
339 static_assert(SafeGe(2, 1), ""); | |
340 static_assert(SafeGe(2, 1u), ""); | |
341 static_assert(SafeGe(2u, 1), ""); | |
342 static_assert(SafeGe(2u, 1u), ""); | |
343 | |
344 static_assert(SafeGe(2, 2), ""); | |
345 static_assert(SafeGe(2, 2u), ""); | |
346 static_assert(SafeGe(2u, 2), ""); | |
347 static_assert(SafeGe(2u, 2u), ""); | |
348 | |
349 static_assert(SafeGe(imin, imin), ""); | |
350 static_assert(!SafeGe(imin, umax), ""); | |
351 static_assert(SafeGe(umax, imin), ""); | |
352 static_assert(SafeGe(umax, umax), ""); | |
353 | |
354 static_assert(SafeGe(m1, m1), ""); | |
355 static_assert(!SafeGe(m1, umax), ""); | |
356 static_assert(SafeGe(umax, m1), ""); | |
357 static_assert(SafeGe(umax, umax), ""); | |
358 | |
359 static_assert(!SafeGe(1, 2), ""); | |
360 static_assert(!SafeGe(1, 2.0), ""); | |
361 static_assert(!SafeGe(1.0, 2), ""); | |
362 static_assert(!SafeGe(1.0, 2.0), ""); | |
363 static_assert(SafeGe(2, 1), ""); | |
364 static_assert(SafeGe(2, 1.0), ""); | |
365 static_assert(SafeGe(2.0, 1), ""); | |
366 static_assert(SafeGe(2.0, 1.0), ""); | |
367 | |
368 static_assert(SafeGe(2, 2), ""); | |
369 static_assert(SafeGe(2, 2.0), ""); | |
370 static_assert(SafeGe(2.0, 2), ""); | |
371 static_assert(SafeGe(2.0, 2.0), ""); | |
372 | |
373 EXPECT_TRUE(SafeGe(p1, p1)); | |
374 EXPECT_FALSE(SafeGe(p1, p2)); | |
375 EXPECT_TRUE(SafeGe(p2, p1)); | |
376 EXPECT_TRUE(SafeGe(p2, p2)); | |
377 } | |
378 | |
379 TEST(SafeCmpTest, Enum) { | |
380 enum E1 { e1 = 13 }; | |
381 enum { e2 = 13 }; | |
382 enum E3 : unsigned { e3 = 13 }; | |
383 enum : unsigned { e4 = 13 }; | |
384 static_assert(SafeEq(13, e1), ""); | |
385 static_assert(SafeEq(13u, e1), ""); | |
386 static_assert(SafeEq(13, e2), ""); | |
387 static_assert(SafeEq(13u, e2), ""); | |
388 static_assert(SafeEq(13, e3), ""); | |
389 static_assert(SafeEq(13u, e3), ""); | |
390 static_assert(SafeEq(13, e4), ""); | |
391 static_assert(SafeEq(13u, e4), ""); | |
392 } | |
393 | |
394 } // namespace rtc | |
OLD | NEW |