| 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 |