safe_numerics_unittest.cc 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846
  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.
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <limits>
  7. #include <type_traits>
  8. #include "base/compiler_specific.h"
  9. #include "build/build_config.h"
  10. // WARNING: This block must come before the base/numerics headers are included.
  11. // These tests deliberately cause arithmetic boundary errors. If the compiler is
  12. // aggressive enough, it can const detect these errors, so we disable warnings.
  13. #if BUILDFLAG(IS_WIN)
  14. #pragma warning(disable : 4756) // Arithmetic overflow.
  15. #pragma warning(disable : 4293) // Invalid shift.
  16. #endif
  17. // This may not need to come before the base/numerics headers, but let's keep
  18. // it close to the MSVC equivalent.
  19. #if defined(__clang__)
  20. #pragma clang diagnostic push
  21. #pragma clang diagnostic ignored "-Winteger-overflow"
  22. #endif
  23. #include "base/logging.h"
  24. #include "base/numerics/safe_conversions.h"
  25. #include "base/numerics/safe_math.h"
  26. #include "base/test/gtest_util.h"
  27. #include "testing/gtest/include/gtest/gtest.h"
  28. #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
  29. #include <mmintrin.h>
  30. #endif
  31. namespace base {
  32. namespace internal {
  33. using std::numeric_limits;
  34. // This is a helper function for finding the maximum value in Src that can be
  35. // wholy represented as the destination floating-point type.
  36. template <typename Dst, typename Src>
  37. Dst GetMaxConvertibleToFloat() {
  38. using DstLimits = numeric_limits<Dst>;
  39. using SrcLimits = numeric_limits<Src>;
  40. static_assert(SrcLimits::is_specialized, "Source must be numeric.");
  41. static_assert(DstLimits::is_specialized, "Destination must be numeric.");
  42. CHECK(DstLimits::is_iec559);
  43. if (SrcLimits::digits <= DstLimits::digits &&
  44. MaxExponent<Src>::value <= MaxExponent<Dst>::value)
  45. return SrcLimits::max();
  46. Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
  47. while (max != static_cast<Src>(static_cast<Dst>(max))) {
  48. max /= 2;
  49. }
  50. return static_cast<Dst>(max);
  51. }
  52. // Test corner case promotions used
  53. static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int8_t>::value, "");
  54. static_assert(IsIntegerArithmeticSafe<int32_t, int16_t, int8_t>::value, "");
  55. static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int16_t>::value, "");
  56. static_assert(!IsIntegerArithmeticSafe<int32_t, int32_t, int8_t>::value, "");
  57. static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
  58. static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
  59. static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
  60. static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
  61. static_assert(
  62. std::is_same<BigEnoughPromotion<int16_t, int8_t>::type, int16_t>::value,
  63. "");
  64. static_assert(
  65. std::is_same<BigEnoughPromotion<int32_t, uint32_t>::type, int64_t>::value,
  66. "");
  67. static_assert(
  68. std::is_same<BigEnoughPromotion<intmax_t, int8_t>::type, intmax_t>::value,
  69. "");
  70. static_assert(
  71. std::is_same<BigEnoughPromotion<uintmax_t, int8_t>::type, uintmax_t>::value,
  72. "");
  73. static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
  74. static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
  75. static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
  76. static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
  77. static_assert(
  78. std::is_same<FastIntegerArithmeticPromotion<int16_t, int8_t>::type,
  79. int32_t>::value,
  80. "");
  81. static_assert(
  82. std::is_same<FastIntegerArithmeticPromotion<int32_t, uint32_t>::type,
  83. int64_t>::value,
  84. "");
  85. static_assert(
  86. std::is_same<FastIntegerArithmeticPromotion<intmax_t, int8_t>::type,
  87. intmax_t>::value,
  88. "");
  89. static_assert(
  90. std::is_same<FastIntegerArithmeticPromotion<uintmax_t, int8_t>::type,
  91. uintmax_t>::value,
  92. "");
  93. static_assert(FastIntegerArithmeticPromotion<int16_t, int8_t>::is_contained,
  94. "");
  95. static_assert(FastIntegerArithmeticPromotion<int32_t, uint32_t>::is_contained,
  96. "");
  97. static_assert(!FastIntegerArithmeticPromotion<intmax_t, int8_t>::is_contained,
  98. "");
  99. static_assert(!FastIntegerArithmeticPromotion<uintmax_t, int8_t>::is_contained,
  100. "");
  101. // Test compile-time (constexpr) evaluation of checking and saturation.
  102. constexpr int32_t kIntOne = 1;
  103. static_assert(1 == checked_cast<uint8_t>(kIntOne), "");
  104. static_assert(1 == saturated_cast<uint8_t>(kIntOne), "");
  105. static_assert(2U == MakeClampedNum(kIntOne) + 1, "");
  106. static_assert(2U == (MakeCheckedNum(kIntOne) + 1).ValueOrDie(), "");
  107. static_assert(0U == MakeClampedNum(kIntOne) - 1, "");
  108. static_assert(0U == (MakeCheckedNum(kIntOne) - 1).ValueOrDie(), "");
  109. static_assert(-1 == -MakeClampedNum(kIntOne), "");
  110. static_assert(-1 == (-MakeCheckedNum(kIntOne)).ValueOrDie(), "");
  111. static_assert(1U == MakeClampedNum(kIntOne) * 1, "");
  112. static_assert(1U == (MakeCheckedNum(kIntOne) * 1).ValueOrDie(), "");
  113. static_assert(1U == MakeClampedNum(kIntOne) / 1, "");
  114. static_assert(1U == (MakeCheckedNum(kIntOne) / 1).ValueOrDie(), "");
  115. static_assert(1 == MakeClampedNum(-kIntOne).Abs(), "");
  116. static_assert(1 == MakeCheckedNum(-kIntOne).Abs().ValueOrDie(), "");
  117. static_assert(1U == MakeClampedNum(kIntOne) % 2, "");
  118. static_assert(1U == (MakeCheckedNum(kIntOne) % 2).ValueOrDie(), "");
  119. static_assert(0U == MakeClampedNum(kIntOne) >> 1U, "");
  120. static_assert(0U == (MakeCheckedNum(kIntOne) >> 1U).ValueOrDie(), "");
  121. static_assert(2U == MakeClampedNum(kIntOne) << 1U, "");
  122. static_assert(2U == (MakeCheckedNum(kIntOne) << 1U).ValueOrDie(), "");
  123. static_assert(1 == MakeClampedNum(kIntOne) & 1U, "");
  124. static_assert(1 == (MakeCheckedNum(kIntOne) & 1U).ValueOrDie(), "");
  125. static_assert(1 == MakeClampedNum(kIntOne) | 1U, "");
  126. static_assert(1 == (MakeCheckedNum(kIntOne) | 1U).ValueOrDie(), "");
  127. static_assert(0 == MakeClampedNum(kIntOne) ^ 1U, "");
  128. static_assert(0 == (MakeCheckedNum(kIntOne) ^ 1U).ValueOrDie(), "");
  129. constexpr float kFloatOne = 1.0;
  130. static_assert(1 == int{checked_cast<int8_t>(kFloatOne)}, "");
  131. static_assert(1 == int{saturated_cast<int8_t>(kFloatOne)}, "");
  132. static_assert(2U == unsigned{MakeClampedNum(kFloatOne) + 1}, "");
  133. static_assert(2U ==
  134. (MakeCheckedNum(kFloatOne) + 1).Cast<unsigned>().ValueOrDie(),
  135. "");
  136. static_assert(0U == unsigned{MakeClampedNum(kFloatOne) - 1}, "");
  137. static_assert(0U ==
  138. (MakeCheckedNum(kFloatOne) - 1).Cast<unsigned>().ValueOrDie(),
  139. "");
  140. static_assert(-1 == int{-MakeClampedNum(kFloatOne)}, "");
  141. static_assert(-1 == (-MakeCheckedNum(kFloatOne)).Cast<int>().ValueOrDie(), "");
  142. static_assert(1U == unsigned{MakeClampedNum(kFloatOne) * 1}, "");
  143. static_assert(1U ==
  144. (MakeCheckedNum(kFloatOne) * 1).Cast<unsigned>().ValueOrDie(),
  145. "");
  146. static_assert(1U == unsigned{MakeClampedNum(kFloatOne) / 1}, "");
  147. static_assert(1U ==
  148. (MakeCheckedNum(kFloatOne) / 1).Cast<unsigned>().ValueOrDie(),
  149. "");
  150. static_assert(1 == int{MakeClampedNum(-kFloatOne).Abs()}, "");
  151. static_assert(1 == MakeCheckedNum(-kFloatOne).Abs().Cast<int>().ValueOrDie(),
  152. "");
  153. template <typename U>
  154. U GetNumericValueForTest(const CheckedNumeric<U>& src) {
  155. return src.state_.value();
  156. }
  157. template <typename U>
  158. U GetNumericValueForTest(const ClampedNumeric<U>& src) {
  159. return static_cast<U>(src);
  160. }
  161. template <typename U>
  162. U GetNumericValueForTest(const U& src) {
  163. return src;
  164. }
  165. // Logs the ValueOrDie() failure instead of crashing.
  166. struct LogOnFailure {
  167. template <typename T>
  168. static T HandleFailure() {
  169. LOG(WARNING) << "ValueOrDie() failed unexpectedly.";
  170. return T();
  171. }
  172. };
  173. template <typename T>
  174. constexpr T GetValue(const T& src) {
  175. return src;
  176. }
  177. template <typename T, typename U>
  178. constexpr T GetValueAsDest(const U& src) {
  179. return static_cast<T>(src);
  180. }
  181. template <typename T>
  182. constexpr T GetValue(const CheckedNumeric<T>& src) {
  183. return src.template ValueOrDie<T, LogOnFailure>();
  184. }
  185. template <typename T, typename U>
  186. constexpr T GetValueAsDest(const CheckedNumeric<U>& src) {
  187. return src.template ValueOrDie<T, LogOnFailure>();
  188. }
  189. template <typename T>
  190. constexpr T GetValue(const ClampedNumeric<T>& src) {
  191. return static_cast<T>(src);
  192. }
  193. template <typename T, typename U>
  194. constexpr T GetValueAsDest(const ClampedNumeric<U>& src) {
  195. return static_cast<T>(src);
  196. }
  197. // Helper macros to wrap displaying the conversion types and line numbers.
  198. #define TEST_EXPECTED_VALIDITY(expected, actual) \
  199. EXPECT_EQ(expected, (actual).template Cast<Dst>().IsValid()) \
  200. << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
  201. << dst << " on line " << line
  202. #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
  203. #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
  204. // We have to handle promotions, so infer the underlying type below from actual.
  205. #define TEST_EXPECTED_VALUE(expected, actual) \
  206. EXPECT_EQ(GetValue(expected), GetValueAsDest<decltype(expected)>(actual)) \
  207. << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
  208. << dst << " on line " << line
  209. // Test the simple pointer arithmetic overrides.
  210. template <typename Dst>
  211. void TestStrictPointerMath() {
  212. Dst dummy_value = 0;
  213. Dst* dummy_ptr = &dummy_value;
  214. static const Dst kDummyOffset = 2; // Don't want to go too far.
  215. EXPECT_EQ(dummy_ptr + kDummyOffset,
  216. dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
  217. EXPECT_EQ(dummy_ptr - kDummyOffset,
  218. dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
  219. EXPECT_NE(dummy_ptr, dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
  220. EXPECT_NE(dummy_ptr, dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
  221. EXPECT_DEATH_IF_SUPPORTED(
  222. dummy_ptr + StrictNumeric<size_t>(std::numeric_limits<size_t>::max()),
  223. "");
  224. }
  225. // Signed integer arithmetic.
  226. template <typename Dst>
  227. static void TestSpecializedArithmetic(
  228. const char* dst,
  229. int line,
  230. typename std::enable_if<numeric_limits<Dst>::is_integer &&
  231. numeric_limits<Dst>::is_signed,
  232. int>::type = 0) {
  233. using DstLimits = SaturationDefaultLimits<Dst>;
  234. TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest()));
  235. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
  236. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
  237. TEST_EXPECTED_VALUE(DstLimits::max(),
  238. MakeCheckedNum(-DstLimits::max()).Abs());
  239. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  240. -ClampedNumeric<Dst>(DstLimits::lowest()));
  241. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  242. ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
  243. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
  244. TEST_EXPECTED_VALUE(DstLimits::max(),
  245. MakeClampedNum(-DstLimits::max()).Abs());
  246. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
  247. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
  248. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
  249. DstLimits::lowest());
  250. TEST_EXPECTED_VALUE(DstLimits::max() - 1,
  251. ClampedNumeric<Dst>(DstLimits::max()) + -1);
  252. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  253. ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
  254. TEST_EXPECTED_VALUE(
  255. DstLimits::Underflow(),
  256. ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
  257. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
  258. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) - -1);
  259. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
  260. DstLimits::lowest());
  261. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
  262. DstLimits::max());
  263. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  264. ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
  265. TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
  266. ClampedNumeric<Dst>(DstLimits::lowest()) - -1);
  267. TEST_EXPECTED_VALUE(
  268. DstLimits::Overflow(),
  269. ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
  270. TEST_EXPECTED_VALUE(
  271. DstLimits::Underflow(),
  272. ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
  273. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
  274. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  275. ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
  276. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1);
  277. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
  278. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1);
  279. TEST_EXPECTED_VALUE(DstLimits::max(),
  280. CheckedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
  281. TEST_EXPECTED_VALUE(DstLimits::max(),
  282. CheckedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
  283. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  284. CheckedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
  285. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  286. CheckedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
  287. TEST_EXPECTED_VALUE(
  288. typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
  289. MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
  290. TEST_EXPECTED_VALUE(DstLimits::max(),
  291. MakeCheckedNum(DstLimits::max()).UnsignedAbs());
  292. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
  293. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
  294. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs());
  295. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  296. ClampedNumeric<Dst>(DstLimits::lowest()) / -1);
  297. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) / 2);
  298. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  299. ClampedNumeric<Dst>(DstLimits::lowest()) * -1);
  300. TEST_EXPECTED_VALUE(DstLimits::max(),
  301. ClampedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
  302. TEST_EXPECTED_VALUE(DstLimits::max(),
  303. ClampedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
  304. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  305. ClampedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
  306. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  307. ClampedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
  308. TEST_EXPECTED_VALUE(
  309. typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
  310. MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
  311. TEST_EXPECTED_VALUE(DstLimits::max(),
  312. MakeClampedNum(DstLimits::max()).UnsignedAbs());
  313. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
  314. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
  315. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).UnsignedAbs());
  316. // Modulus is legal only for integers.
  317. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 2);
  318. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 1);
  319. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -1);
  320. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -2);
  321. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
  322. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
  323. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % -1);
  324. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % -2);
  325. TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
  326. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % 1);
  327. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % -1);
  328. TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % -2);
  329. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
  330. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 1);
  331. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -1);
  332. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -2);
  333. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
  334. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % 1);
  335. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % -1);
  336. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % -2);
  337. // Test all the different modulus combinations.
  338. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
  339. TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
  340. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
  341. CheckedNumeric<Dst> checked_dst = 1;
  342. TEST_EXPECTED_VALUE(0, checked_dst %= 1);
  343. // Test that div by 0 is avoided but returns invalid result.
  344. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
  345. // Test bit shifts.
  346. volatile Dst negative_one = -1;
  347. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
  348. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
  349. << (IntegerBitsPlusSign<Dst>::value - 1));
  350. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
  351. << IntegerBitsPlusSign<Dst>::value);
  352. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
  353. TEST_EXPECTED_VALUE(
  354. static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2),
  355. CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2));
  356. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0)
  357. << (IntegerBitsPlusSign<Dst>::value - 1));
  358. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
  359. TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
  360. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
  361. IntegerBitsPlusSign<Dst>::value);
  362. TEST_EXPECTED_VALUE(
  363. 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
  364. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
  365. // Modulus is legal only for integers.
  366. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 2);
  367. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 1);
  368. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -1);
  369. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -2);
  370. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
  371. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
  372. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % -1);
  373. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % -2);
  374. TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % 2);
  375. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % 1);
  376. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % -1);
  377. TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % -2);
  378. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
  379. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 1);
  380. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -1);
  381. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -2);
  382. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
  383. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % 1);
  384. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % -1);
  385. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % -2);
  386. // Test all the different modulus combinations.
  387. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
  388. TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
  389. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
  390. ClampedNumeric<Dst> clamped_dst = 1;
  391. TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
  392. TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
  393. // Test bit shifts.
  394. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  395. ClampedNumeric<Dst>(1)
  396. << (IntegerBitsPlusSign<Dst>::value - 1U));
  397. TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0)
  398. << (IntegerBitsPlusSign<Dst>::value + 0U));
  399. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  400. ClampedNumeric<Dst>(DstLimits::max()) << 1U);
  401. TEST_EXPECTED_VALUE(
  402. static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U),
  403. ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U));
  404. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0)
  405. << (IntegerBitsPlusSign<Dst>::value - 1U));
  406. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
  407. TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
  408. TEST_EXPECTED_VALUE(
  409. 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value + 0U));
  410. TEST_EXPECTED_VALUE(
  411. 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
  412. TEST_EXPECTED_VALUE(
  413. -1, ClampedNumeric<Dst>(-1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
  414. TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(DstLimits::lowest()) >>
  415. (IntegerBitsPlusSign<Dst>::value - 0U));
  416. TestStrictPointerMath<Dst>();
  417. }
  418. // Unsigned integer arithmetic.
  419. template <typename Dst>
  420. static void TestSpecializedArithmetic(
  421. const char* dst,
  422. int line,
  423. typename std::enable_if<numeric_limits<Dst>::is_integer &&
  424. !numeric_limits<Dst>::is_signed,
  425. int>::type = 0) {
  426. using DstLimits = SaturationDefaultLimits<Dst>;
  427. TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
  428. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
  429. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
  430. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
  431. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
  432. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
  433. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
  434. TEST_EXPECTED_SUCCESS(
  435. CheckedNumeric<typename std::make_signed<Dst>::type>(
  436. std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
  437. .UnsignedAbs());
  438. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  439. MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
  440. TEST_EXPECTED_VALUE(DstLimits::max(),
  441. MakeCheckedNum(DstLimits::max()).UnsignedAbs());
  442. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
  443. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
  444. TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>(DstLimits::lowest()));
  445. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
  446. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  447. ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
  448. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  449. ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
  450. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
  451. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) / 2);
  452. TEST_EXPECTED_VALUE(0,
  453. ClampedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
  454. TEST_EXPECTED_VALUE(
  455. as_unsigned(
  456. std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()),
  457. ClampedNumeric<typename std::make_signed<Dst>::type>(
  458. std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
  459. .UnsignedAbs());
  460. TEST_EXPECTED_VALUE(DstLimits::lowest(),
  461. MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
  462. TEST_EXPECTED_VALUE(DstLimits::max(),
  463. MakeClampedNum(DstLimits::max()).UnsignedAbs());
  464. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
  465. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
  466. // Modulus is legal only for integers.
  467. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
  468. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
  469. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
  470. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
  471. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
  472. // Test all the different modulus combinations.
  473. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
  474. TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
  475. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
  476. CheckedNumeric<Dst> checked_dst = 1;
  477. TEST_EXPECTED_VALUE(0, checked_dst %= 1);
  478. // Test that div by 0 is avoided but returns invalid result.
  479. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
  480. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
  481. << IntegerBitsPlusSign<Dst>::value);
  482. // Test bit shifts.
  483. volatile int negative_one = -1;
  484. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
  485. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
  486. << IntegerBitsPlusSign<Dst>::value);
  487. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
  488. << IntegerBitsPlusSign<Dst>::value);
  489. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
  490. TEST_EXPECTED_VALUE(
  491. static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1),
  492. CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1));
  493. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
  494. TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
  495. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
  496. IntegerBitsPlusSign<Dst>::value);
  497. TEST_EXPECTED_VALUE(
  498. 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
  499. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
  500. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) & 1);
  501. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
  502. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) & 1);
  503. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
  504. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  505. MakeCheckedNum(DstLimits::max()) & -1);
  506. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 1);
  507. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 0);
  508. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) | 1);
  509. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) | 0);
  510. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  511. CheckedNumeric<Dst>(0) | static_cast<Dst>(-1));
  512. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1);
  513. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0);
  514. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1);
  515. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0);
  516. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  517. CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
  518. TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0));
  519. // Modulus is legal only for integers.
  520. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
  521. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
  522. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
  523. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
  524. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
  525. // Test all the different modulus combinations.
  526. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
  527. TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
  528. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
  529. ClampedNumeric<Dst> clamped_dst = 1;
  530. TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
  531. // Test that div by 0 is avoided but returns invalid result.
  532. TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
  533. // Test bit shifts.
  534. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  535. ClampedNumeric<Dst>(1)
  536. << as_unsigned(IntegerBitsPlusSign<Dst>::value));
  537. TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0) << as_unsigned(
  538. IntegerBitsPlusSign<Dst>::value));
  539. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  540. ClampedNumeric<Dst>(DstLimits::max()) << 1U);
  541. TEST_EXPECTED_VALUE(
  542. static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U),
  543. ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U));
  544. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
  545. TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
  546. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) >>
  547. as_unsigned(IntegerBitsPlusSign<Dst>::value));
  548. TEST_EXPECTED_VALUE(
  549. 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
  550. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) & 1);
  551. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
  552. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) & 1);
  553. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
  554. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  555. MakeClampedNum(DstLimits::max()) & -1);
  556. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 1);
  557. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 0);
  558. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) | 1);
  559. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) | 0);
  560. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  561. ClampedNumeric<Dst>(0) | static_cast<Dst>(-1));
  562. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) ^ 1);
  563. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) ^ 0);
  564. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) ^ 1);
  565. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) ^ 0);
  566. TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
  567. ClampedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
  568. TEST_EXPECTED_VALUE(DstLimits::max(), ~ClampedNumeric<Dst>(0));
  569. TestStrictPointerMath<Dst>();
  570. }
  571. // Floating point arithmetic.
  572. template <typename Dst>
  573. void TestSpecializedArithmetic(
  574. const char* dst,
  575. int line,
  576. typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
  577. using DstLimits = SaturationDefaultLimits<Dst>;
  578. TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
  579. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
  580. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
  581. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
  582. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
  583. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
  584. DstLimits::lowest());
  585. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
  586. DstLimits::lowest());
  587. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
  588. DstLimits::max());
  589. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
  590. TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
  591. TEST_EXPECTED_VALUE(DstLimits::max(),
  592. -ClampedNumeric<Dst>(DstLimits::lowest()));
  593. TEST_EXPECTED_VALUE(DstLimits::max(),
  594. ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
  595. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
  596. TEST_EXPECTED_VALUE(DstLimits::lowest() - 1,
  597. ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
  598. TEST_EXPECTED_VALUE(DstLimits::max() + 1,
  599. ClampedNumeric<Dst>(DstLimits::max()) + 1);
  600. TEST_EXPECTED_VALUE(
  601. DstLimits::Underflow(),
  602. ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
  603. TEST_EXPECTED_VALUE(
  604. DstLimits::Overflow(),
  605. ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
  606. TEST_EXPECTED_VALUE(
  607. DstLimits::Underflow(),
  608. ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
  609. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  610. ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
  611. TEST_EXPECTED_VALUE(-0.5, ClampedNumeric<Dst>(-1.0) / 2);
  612. }
  613. // Generic arithmetic tests.
  614. template <typename Dst>
  615. static void TestArithmetic(const char* dst, int line) {
  616. using DstLimits = SaturationDefaultLimits<Dst>;
  617. EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
  618. EXPECT_EQ(false, CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
  619. DstLimits::max())
  620. .IsValid());
  621. EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
  622. EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
  623. EXPECT_EQ(static_cast<Dst>(1),
  624. CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
  625. DstLimits::max())
  626. .ValueOrDefault(1));
  627. // Test the operator combinations.
  628. TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
  629. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
  630. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
  631. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
  632. TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
  633. TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
  634. TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
  635. TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
  636. TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
  637. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
  638. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
  639. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
  640. CheckedNumeric<Dst> checked_dst = 1;
  641. TEST_EXPECTED_VALUE(2, checked_dst += 1);
  642. checked_dst = 1;
  643. TEST_EXPECTED_VALUE(0, checked_dst -= 1);
  644. checked_dst = 1;
  645. TEST_EXPECTED_VALUE(1, checked_dst *= 1);
  646. checked_dst = 1;
  647. TEST_EXPECTED_VALUE(1, checked_dst /= 1);
  648. TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + ClampedNumeric<Dst>(1));
  649. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - ClampedNumeric<Dst>(1));
  650. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * ClampedNumeric<Dst>(1));
  651. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / ClampedNumeric<Dst>(1));
  652. TEST_EXPECTED_VALUE(2, 1 + ClampedNumeric<Dst>(1));
  653. TEST_EXPECTED_VALUE(0, 1 - ClampedNumeric<Dst>(1));
  654. TEST_EXPECTED_VALUE(1, 1 * ClampedNumeric<Dst>(1));
  655. TEST_EXPECTED_VALUE(1, 1 / ClampedNumeric<Dst>(1));
  656. TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + 1);
  657. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - 1);
  658. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * 1);
  659. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
  660. ClampedNumeric<Dst> clamped_dst = 1;
  661. TEST_EXPECTED_VALUE(2, clamped_dst += 1);
  662. clamped_dst = 1;
  663. TEST_EXPECTED_VALUE(0, clamped_dst -= 1);
  664. clamped_dst = 1;
  665. TEST_EXPECTED_VALUE(1, clamped_dst *= 1);
  666. clamped_dst = 1;
  667. TEST_EXPECTED_VALUE(1, clamped_dst /= 1);
  668. // Generic negation.
  669. if (DstLimits::is_signed) {
  670. TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
  671. TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
  672. TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
  673. TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
  674. -CheckedNumeric<Dst>(DstLimits::max()));
  675. TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>());
  676. TEST_EXPECTED_VALUE(-1, -ClampedNumeric<Dst>(1));
  677. TEST_EXPECTED_VALUE(1, -ClampedNumeric<Dst>(-1));
  678. TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
  679. -ClampedNumeric<Dst>(DstLimits::max()));
  680. // The runtime paths for saturated negation differ significantly from what
  681. // gets evaluated at compile-time. Making this test volatile forces the
  682. // compiler to generate code rather than fold constant expressions.
  683. volatile Dst value = Dst(0);
  684. TEST_EXPECTED_VALUE(0, -MakeClampedNum(value));
  685. value = Dst(1);
  686. TEST_EXPECTED_VALUE(-1, -MakeClampedNum(value));
  687. value = Dst(2);
  688. TEST_EXPECTED_VALUE(-2, -MakeClampedNum(value));
  689. value = Dst(-1);
  690. TEST_EXPECTED_VALUE(1, -MakeClampedNum(value));
  691. value = Dst(-2);
  692. TEST_EXPECTED_VALUE(2, -MakeClampedNum(value));
  693. value = DstLimits::max();
  694. TEST_EXPECTED_VALUE(Dst(DstLimits::max() * -1), -MakeClampedNum(value));
  695. value = Dst(-1 * DstLimits::max());
  696. TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
  697. value = DstLimits::lowest();
  698. TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
  699. }
  700. // Generic absolute value.
  701. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
  702. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
  703. TEST_EXPECTED_VALUE(DstLimits::max(),
  704. CheckedNumeric<Dst>(DstLimits::max()).Abs());
  705. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>().Abs());
  706. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).Abs());
  707. TEST_EXPECTED_VALUE(DstLimits::max(),
  708. ClampedNumeric<Dst>(DstLimits::max()).Abs());
  709. // Generic addition.
  710. TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
  711. TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
  712. if (numeric_limits<Dst>::is_signed)
  713. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
  714. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1);
  715. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
  716. DstLimits::max());
  717. TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>() + 1));
  718. TEST_EXPECTED_VALUE(2, (ClampedNumeric<Dst>(1) + 1));
  719. if (numeric_limits<Dst>::is_signed)
  720. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) + 1));
  721. TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
  722. ClampedNumeric<Dst>(DstLimits::lowest()) + 1);
  723. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  724. ClampedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
  725. // Generic subtraction.
  726. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
  727. TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
  728. if (numeric_limits<Dst>::is_signed) {
  729. TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
  730. TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
  731. } else {
  732. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1);
  733. }
  734. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(1) - 1));
  735. TEST_EXPECTED_VALUE(DstLimits::max() - 1,
  736. ClampedNumeric<Dst>(DstLimits::max()) - 1);
  737. if (numeric_limits<Dst>::is_signed) {
  738. TEST_EXPECTED_VALUE(-1, (ClampedNumeric<Dst>() - 1));
  739. TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) - 1));
  740. } else {
  741. TEST_EXPECTED_VALUE(DstLimits::max(),
  742. ClampedNumeric<Dst>(DstLimits::max()) - -1);
  743. }
  744. // Generic multiplication.
  745. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
  746. TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
  747. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
  748. if (numeric_limits<Dst>::is_signed) {
  749. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
  750. TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
  751. TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
  752. } else {
  753. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2);
  754. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
  755. CheckedNumeric<uintmax_t>(-2));
  756. }
  757. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
  758. DstLimits::max());
  759. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>() * 1));
  760. TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>(1) * 1));
  761. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * 0));
  762. if (numeric_limits<Dst>::is_signed) {
  763. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) * 0));
  764. TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * -1));
  765. TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) * 2));
  766. } else {
  767. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  768. ClampedNumeric<Dst>(DstLimits::max()) * -2);
  769. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) *
  770. ClampedNumeric<uintmax_t>(-2));
  771. }
  772. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  773. ClampedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
  774. // Generic division.
  775. TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
  776. TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
  777. TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
  778. CheckedNumeric<Dst>(DstLimits::lowest()) / 2);
  779. TEST_EXPECTED_VALUE(DstLimits::max() / 2,
  780. CheckedNumeric<Dst>(DstLimits::max()) / 2);
  781. TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) / 0);
  782. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() / 1);
  783. TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
  784. TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
  785. ClampedNumeric<Dst>(DstLimits::lowest()) / 2);
  786. TEST_EXPECTED_VALUE(DstLimits::max() / 2,
  787. ClampedNumeric<Dst>(DstLimits::max()) / 2);
  788. TEST_EXPECTED_VALUE(DstLimits::Overflow(), ClampedNumeric<Dst>(1) / 0);
  789. TEST_EXPECTED_VALUE(DstLimits::Underflow(), ClampedNumeric<Dst>(-1) / 0);
  790. TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) / 0);
  791. TestSpecializedArithmetic<Dst>(dst, line);
  792. }
  793. // Helper macro to wrap displaying the conversion types and line numbers.
  794. #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
  795. TEST(SafeNumerics, SignedIntegerMath) {
  796. TEST_ARITHMETIC(int8_t);
  797. TEST_ARITHMETIC(int16_t);
  798. TEST_ARITHMETIC(int);
  799. TEST_ARITHMETIC(intptr_t);
  800. TEST_ARITHMETIC(intmax_t);
  801. }
  802. TEST(SafeNumerics, UnsignedIntegerMath) {
  803. TEST_ARITHMETIC(uint8_t);
  804. TEST_ARITHMETIC(uint16_t);
  805. TEST_ARITHMETIC(unsigned int);
  806. TEST_ARITHMETIC(uintptr_t);
  807. TEST_ARITHMETIC(uintmax_t);
  808. }
  809. TEST(SafeNumerics, FloatingPointMath) {
  810. TEST_ARITHMETIC(float);
  811. TEST_ARITHMETIC(double);
  812. }
  813. // Enumerates the five different conversions types we need to test.
  814. enum NumericConversionType {
  815. SIGN_PRESERVING_VALUE_PRESERVING,
  816. SIGN_PRESERVING_NARROW,
  817. SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
  818. SIGN_TO_UNSIGN_NARROW,
  819. UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
  820. };
  821. // Template covering the different conversion tests.
  822. template <typename Dst, typename Src, NumericConversionType conversion>
  823. struct TestNumericConversion {};
  824. enum RangeConstraint {
  825. RANGE_VALID = 0x0, // Value can be represented by the destination type.
  826. RANGE_UNDERFLOW = 0x1, // Value would underflow.
  827. RANGE_OVERFLOW = 0x2, // Value would overflow.
  828. RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN).
  829. };
  830. // These are some wrappers to make the tests a bit cleaner.
  831. constexpr RangeConstraint RangeCheckToEnum(const RangeCheck constraint) {
  832. return static_cast<RangeConstraint>(
  833. static_cast<int>(constraint.IsOverflowFlagSet()) << 1 |
  834. static_cast<int>(constraint.IsUnderflowFlagSet()));
  835. }
  836. // EXPECT_EQ wrappers providing specific detail on test failures.
  837. #define TEST_EXPECTED_RANGE(expected, actual) \
  838. EXPECT_EQ(expected, \
  839. RangeCheckToEnum(DstRangeRelationToSrcRange<Dst>(actual))) \
  840. << "Conversion test: " << src << " value " << actual << " to " << dst \
  841. << " on line " << line
  842. template <typename Dst, typename Src>
  843. void TestStrictComparison(const char* dst, const char* src, int line) {
  844. using DstLimits = numeric_limits<Dst>;
  845. using SrcLimits = numeric_limits<Src>;
  846. static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), "");
  847. static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), "");
  848. static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()),
  849. "");
  850. static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= SrcLimits::max()),
  851. "");
  852. static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= DstLimits::max(),
  853. "");
  854. static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= SrcLimits::max(),
  855. "");
  856. static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > DstLimits::max()),
  857. "");
  858. static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > SrcLimits::max()),
  859. "");
  860. static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::lowest(), "");
  861. static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::lowest(), "");
  862. static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::lowest()),
  863. "");
  864. static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::lowest()),
  865. "");
  866. static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::lowest(),
  867. "");
  868. static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::lowest(),
  869. "");
  870. static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::lowest()),
  871. "");
  872. static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::lowest()),
  873. "");
  874. static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1),
  875. "");
  876. static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0),
  877. "");
  878. static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0),
  879. "");
  880. static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::lowest(),
  881. "");
  882. static_assert(
  883. !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), "");
  884. static_assert(
  885. !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), "");
  886. // Due to differences in float handling between compilers, these aren't
  887. // compile-time constants everywhere. So, we use run-time tests.
  888. EXPECT_EQ(
  889. SrcLimits::max(),
  890. MakeCheckedNum(SrcLimits::max()).Max(DstLimits::lowest()).ValueOrDie());
  891. EXPECT_EQ(
  892. DstLimits::max(),
  893. MakeCheckedNum(SrcLimits::lowest()).Max(DstLimits::max()).ValueOrDie());
  894. EXPECT_EQ(
  895. DstLimits::lowest(),
  896. MakeCheckedNum(SrcLimits::max()).Min(DstLimits::lowest()).ValueOrDie());
  897. EXPECT_EQ(
  898. SrcLimits::lowest(),
  899. MakeCheckedNum(SrcLimits::lowest()).Min(DstLimits::max()).ValueOrDie());
  900. EXPECT_EQ(SrcLimits::lowest(), CheckMin(MakeStrictNum(1), MakeCheckedNum(0),
  901. DstLimits::max(), SrcLimits::lowest())
  902. .ValueOrDie());
  903. EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0),
  904. DstLimits::max(), SrcLimits::lowest())
  905. .ValueOrDie());
  906. EXPECT_EQ(SrcLimits::max(),
  907. MakeClampedNum(SrcLimits::max()).Max(DstLimits::lowest()));
  908. EXPECT_EQ(DstLimits::max(),
  909. MakeClampedNum(SrcLimits::lowest()).Max(DstLimits::max()));
  910. EXPECT_EQ(DstLimits::lowest(),
  911. MakeClampedNum(SrcLimits::max()).Min(DstLimits::lowest()));
  912. EXPECT_EQ(SrcLimits::lowest(),
  913. MakeClampedNum(SrcLimits::lowest()).Min(DstLimits::max()));
  914. EXPECT_EQ(SrcLimits::lowest(),
  915. ClampMin(MakeStrictNum(1), MakeClampedNum(0), DstLimits::max(),
  916. SrcLimits::lowest()));
  917. EXPECT_EQ(DstLimits::max(), ClampMax(MakeStrictNum(1), MakeClampedNum(0),
  918. DstLimits::max(), SrcLimits::lowest()));
  919. if (IsValueInRangeForNumericType<Dst>(SrcLimits::max())) {
  920. TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), (CommonMax<Dst, Src>()));
  921. TEST_EXPECTED_VALUE(Dst(SrcLimits::max()),
  922. (CommonMaxOrMin<Dst, Src>(false)));
  923. } else {
  924. TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMax<Dst, Src>()));
  925. TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMaxOrMin<Dst, Src>(false)));
  926. }
  927. if (IsValueInRangeForNumericType<Dst>(SrcLimits::lowest())) {
  928. TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()), (CommonMin<Dst, Src>()));
  929. TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()),
  930. (CommonMaxOrMin<Dst, Src>(true)));
  931. } else {
  932. TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMin<Dst, Src>()));
  933. TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMaxOrMin<Dst, Src>(true)));
  934. }
  935. }
  936. template <typename Dst, typename Src>
  937. struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
  938. static void Test(const char* dst, const char* src, int line) {
  939. using SrcLimits = SaturationDefaultLimits<Src>;
  940. using DstLimits = SaturationDefaultLimits<Dst>;
  941. // Integral to floating.
  942. static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
  943. // Not floating to integral and...
  944. (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
  945. // Same sign, same numeric, source is narrower or same.
  946. ((SrcLimits::is_signed == DstLimits::is_signed &&
  947. MaxExponent<Dst>::value >= MaxExponent<Src>::value) ||
  948. // Or signed destination and source is smaller
  949. (DstLimits::is_signed &&
  950. MaxExponent<Dst>::value >= MaxExponent<Src>::value))),
  951. "Comparison must be sign preserving and value preserving");
  952. TestStrictComparison<Dst, Src>(dst, src, line);
  953. const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
  954. const ClampedNumeric<Dst> clamped_dst = SrcLimits::max();
  955. TEST_EXPECTED_SUCCESS(checked_dst);
  956. TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), clamped_dst);
  957. if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
  958. if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
  959. // At least twice larger type.
  960. TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
  961. TEST_EXPECTED_VALUE(SrcLimits::max() * clamped_dst,
  962. Dst(SrcLimits::max()) * Dst(SrcLimits::max()));
  963. } else { // Larger, but not at least twice as large.
  964. TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
  965. TEST_EXPECTED_SUCCESS(checked_dst + 1);
  966. TEST_EXPECTED_VALUE(DstLimits::Overflow(),
  967. SrcLimits::max() * clamped_dst);
  968. TEST_EXPECTED_VALUE(Dst(SrcLimits::max()) + Dst(1),
  969. clamped_dst + Dst(1));
  970. }
  971. } else { // Same width type.
  972. TEST_EXPECTED_FAILURE(checked_dst + 1);
  973. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + Dst(1));
  974. }
  975. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
  976. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
  977. if (SrcLimits::is_iec559) {
  978. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
  979. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
  980. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
  981. TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
  982. } else if (numeric_limits<Src>::is_signed) {
  983. // This block reverses the Src to Dst relationship so we don't have to
  984. // complicate the test macros.
  985. if (!std::is_same<Src, Dst>::value) {
  986. TEST_EXPECTED_SUCCESS(CheckDiv(SrcLimits::lowest(), Dst(-1)));
  987. }
  988. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
  989. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
  990. }
  991. }
  992. };
  993. template <typename Dst, typename Src>
  994. struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
  995. static void Test(const char* dst, const char* src, int line) {
  996. using SrcLimits = SaturationDefaultLimits<Src>;
  997. using DstLimits = SaturationDefaultLimits<Dst>;
  998. static_assert(SrcLimits::is_signed == DstLimits::is_signed,
  999. "Destination and source sign must be the same");
  1000. static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
  1001. "Destination must be narrower than source");
  1002. TestStrictComparison<Dst, Src>(dst, src, line);
  1003. const CheckedNumeric<Dst> checked_dst;
  1004. TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
  1005. TEST_EXPECTED_VALUE(1, checked_dst + Src(1));
  1006. TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
  1007. ClampedNumeric<Dst> clamped_dst;
  1008. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
  1009. TEST_EXPECTED_VALUE(1, clamped_dst + Src(1));
  1010. TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst - SrcLimits::max());
  1011. clamped_dst += SrcLimits::max();
  1012. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
  1013. clamped_dst = DstLimits::max();
  1014. clamped_dst += SrcLimits::max();
  1015. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
  1016. clamped_dst = DstLimits::max();
  1017. clamped_dst -= SrcLimits::max();
  1018. TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
  1019. clamped_dst = 0;
  1020. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
  1021. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
  1022. if (SrcLimits::is_iec559) {
  1023. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
  1024. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
  1025. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
  1026. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
  1027. TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
  1028. if (DstLimits::is_integer) {
  1029. if (SrcLimits::digits < DstLimits::digits) {
  1030. TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
  1031. static_cast<Src>(DstLimits::max()));
  1032. } else {
  1033. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
  1034. }
  1035. TEST_EXPECTED_RANGE(
  1036. RANGE_VALID,
  1037. static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
  1038. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
  1039. }
  1040. } else if (SrcLimits::is_signed) {
  1041. TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
  1042. TEST_EXPECTED_VALUE(-1, clamped_dst - static_cast<Src>(1));
  1043. TEST_EXPECTED_VALUE(Src(Src(0) - DstLimits::lowest()),
  1044. ClampDiv(DstLimits::lowest(), Src(-1)));
  1045. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
  1046. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
  1047. } else {
  1048. TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
  1049. TEST_EXPECTED_VALUE(Dst(0), clamped_dst - static_cast<Src>(1));
  1050. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
  1051. }
  1052. }
  1053. };
  1054. template <typename Dst, typename Src>
  1055. struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
  1056. static void Test(const char* dst, const char* src, int line) {
  1057. using SrcLimits = SaturationDefaultLimits<Src>;
  1058. using DstLimits = SaturationDefaultLimits<Dst>;
  1059. static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value,
  1060. "Destination must be equal or wider than source.");
  1061. static_assert(SrcLimits::is_signed, "Source must be signed");
  1062. static_assert(!DstLimits::is_signed, "Destination must be unsigned");
  1063. TestStrictComparison<Dst, Src>(dst, src, line);
  1064. const CheckedNumeric<Dst> checked_dst;
  1065. TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
  1066. TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
  1067. TEST_EXPECTED_SUCCESS(checked_dst * static_cast<Src>(-1));
  1068. TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
  1069. TEST_EXPECTED_VALUE(Dst(0), CheckDiv(Dst(0), Src(-1)));
  1070. const ClampedNumeric<Dst> clamped_dst;
  1071. TEST_EXPECTED_VALUE(SrcLimits::max(), clamped_dst + SrcLimits::max());
  1072. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  1073. clamped_dst + static_cast<Src>(-1));
  1074. TEST_EXPECTED_VALUE(0, clamped_dst * static_cast<Src>(-1));
  1075. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  1076. clamped_dst + SrcLimits::lowest());
  1077. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
  1078. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
  1079. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
  1080. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
  1081. }
  1082. };
  1083. template <typename Dst, typename Src>
  1084. struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
  1085. static void Test(const char* dst, const char* src, int line) {
  1086. using SrcLimits = SaturationDefaultLimits<Src>;
  1087. using DstLimits = SaturationDefaultLimits<Dst>;
  1088. static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value,
  1089. "Destination must be narrower than source.");
  1090. static_assert(SrcLimits::is_signed, "Source must be signed.");
  1091. static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
  1092. TestStrictComparison<Dst, Src>(dst, src, line);
  1093. const CheckedNumeric<Dst> checked_dst;
  1094. TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
  1095. TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
  1096. TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
  1097. TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
  1098. ClampedNumeric<Dst> clamped_dst;
  1099. TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
  1100. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
  1101. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  1102. clamped_dst + static_cast<Src>(-1));
  1103. TEST_EXPECTED_VALUE(DstLimits::Underflow(),
  1104. clamped_dst + SrcLimits::lowest());
  1105. clamped_dst += SrcLimits::max();
  1106. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
  1107. clamped_dst = DstLimits::max();
  1108. clamped_dst += SrcLimits::max();
  1109. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
  1110. clamped_dst = DstLimits::max();
  1111. clamped_dst -= SrcLimits::max();
  1112. TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
  1113. clamped_dst = 0;
  1114. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
  1115. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
  1116. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
  1117. // Additional saturation tests.
  1118. EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
  1119. EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest()));
  1120. if (SrcLimits::is_iec559) {
  1121. EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN()));
  1122. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
  1123. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
  1124. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
  1125. TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
  1126. if (DstLimits::is_integer) {
  1127. if (SrcLimits::digits < DstLimits::digits) {
  1128. TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
  1129. static_cast<Src>(DstLimits::max()));
  1130. } else {
  1131. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
  1132. }
  1133. TEST_EXPECTED_RANGE(
  1134. RANGE_VALID,
  1135. static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
  1136. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
  1137. }
  1138. } else {
  1139. TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
  1140. }
  1141. }
  1142. };
  1143. template <typename Dst, typename Src>
  1144. struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
  1145. static void Test(const char* dst, const char* src, int line) {
  1146. using SrcLimits = SaturationDefaultLimits<Src>;
  1147. using DstLimits = SaturationDefaultLimits<Dst>;
  1148. static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
  1149. "Destination must be narrower or equal to source.");
  1150. static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
  1151. static_assert(DstLimits::is_signed, "Destination must be signed.");
  1152. TestStrictComparison<Dst, Src>(dst, src, line);
  1153. const CheckedNumeric<Dst> checked_dst;
  1154. TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
  1155. TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
  1156. TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest());
  1157. const ClampedNumeric<Dst> clamped_dst;
  1158. TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
  1159. TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
  1160. TEST_EXPECTED_VALUE(SrcLimits::lowest(), clamped_dst + SrcLimits::lowest());
  1161. TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
  1162. TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
  1163. TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
  1164. // Additional saturation tests.
  1165. EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
  1166. EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest()));
  1167. }
  1168. };
  1169. // Helper macro to wrap displaying the conversion types and line numbers
  1170. #define TEST_NUMERIC_CONVERSION(d, s, t) \
  1171. TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
  1172. TEST(SafeNumerics, IntMinOperations) {
  1173. TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1174. TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1175. TEST_NUMERIC_CONVERSION(int8_t, int16_t, SIGN_PRESERVING_NARROW);
  1176. TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
  1177. TEST_NUMERIC_CONVERSION(uint8_t, uint16_t, SIGN_PRESERVING_NARROW);
  1178. TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
  1179. TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
  1180. TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1181. TEST_NUMERIC_CONVERSION(uint8_t, int16_t, SIGN_TO_UNSIGN_NARROW);
  1182. TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
  1183. TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
  1184. TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
  1185. TEST_NUMERIC_CONVERSION(int8_t, uint16_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1186. TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1187. TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1188. }
  1189. TEST(SafeNumerics, Int16Operations) {
  1190. TEST_NUMERIC_CONVERSION(int16_t, int16_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1191. TEST_NUMERIC_CONVERSION(uint16_t, uint16_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1192. TEST_NUMERIC_CONVERSION(int16_t, int, SIGN_PRESERVING_NARROW);
  1193. TEST_NUMERIC_CONVERSION(uint16_t, unsigned int, SIGN_PRESERVING_NARROW);
  1194. TEST_NUMERIC_CONVERSION(int16_t, float, SIGN_PRESERVING_NARROW);
  1195. TEST_NUMERIC_CONVERSION(uint16_t, int16_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1196. TEST_NUMERIC_CONVERSION(uint16_t, int, SIGN_TO_UNSIGN_NARROW);
  1197. TEST_NUMERIC_CONVERSION(uint16_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
  1198. TEST_NUMERIC_CONVERSION(uint16_t, float, SIGN_TO_UNSIGN_NARROW);
  1199. TEST_NUMERIC_CONVERSION(int16_t, unsigned int,
  1200. UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1201. TEST_NUMERIC_CONVERSION(int16_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1202. }
  1203. TEST(SafeNumerics, IntOperations) {
  1204. TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
  1205. TEST_NUMERIC_CONVERSION(unsigned int, unsigned int,
  1206. SIGN_PRESERVING_VALUE_PRESERVING);
  1207. TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1208. TEST_NUMERIC_CONVERSION(unsigned int, uint8_t,
  1209. SIGN_PRESERVING_VALUE_PRESERVING);
  1210. TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1211. TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
  1212. TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
  1213. TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
  1214. TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
  1215. TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1216. TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1217. TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
  1218. TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
  1219. TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
  1220. TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1221. TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1222. }
  1223. TEST(SafeNumerics, IntMaxOperations) {
  1224. TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1225. TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t,
  1226. SIGN_PRESERVING_VALUE_PRESERVING);
  1227. TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
  1228. TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int,
  1229. SIGN_PRESERVING_VALUE_PRESERVING);
  1230. TEST_NUMERIC_CONVERSION(intmax_t, unsigned int,
  1231. SIGN_PRESERVING_VALUE_PRESERVING);
  1232. TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1233. TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
  1234. TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
  1235. TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1236. TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1237. TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
  1238. TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
  1239. TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1240. }
  1241. TEST(SafeNumerics, FloatOperations) {
  1242. TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1243. TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1244. TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
  1245. TEST_NUMERIC_CONVERSION(float, unsigned int,
  1246. SIGN_PRESERVING_VALUE_PRESERVING);
  1247. TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
  1248. }
  1249. TEST(SafeNumerics, DoubleOperations) {
  1250. TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1251. TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
  1252. TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
  1253. TEST_NUMERIC_CONVERSION(double, unsigned int,
  1254. SIGN_PRESERVING_VALUE_PRESERVING);
  1255. }
  1256. TEST(SafeNumerics, SizeTOperations) {
  1257. TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
  1258. TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
  1259. }
  1260. // A one-off test to ensure StrictNumeric won't resolve to an incorrect type.
  1261. // If this fails we'll just get a compiler error on an ambiguous overload.
  1262. int TestOverload(int) { // Overload fails.
  1263. return 0;
  1264. }
  1265. uint8_t TestOverload(uint8_t) { // Overload fails.
  1266. return 0;
  1267. }
  1268. size_t TestOverload(size_t) { // Overload succeeds.
  1269. return 0;
  1270. }
  1271. static_assert(
  1272. std::is_same<decltype(TestOverload(StrictNumeric<int>())), int>::value,
  1273. "");
  1274. static_assert(std::is_same<decltype(TestOverload(StrictNumeric<size_t>())),
  1275. size_t>::value,
  1276. "");
  1277. template <typename T>
  1278. struct CastTest1 {
  1279. static constexpr T NaN() { return -1; }
  1280. static constexpr T max() { return numeric_limits<T>::max() - 1; }
  1281. static constexpr T Overflow() { return max(); }
  1282. static constexpr T lowest() { return numeric_limits<T>::lowest() + 1; }
  1283. static constexpr T Underflow() { return lowest(); }
  1284. };
  1285. template <typename T>
  1286. struct CastTest2 {
  1287. static constexpr T NaN() { return 11; }
  1288. static constexpr T max() { return 10; }
  1289. static constexpr T Overflow() { return max(); }
  1290. static constexpr T lowest() { return 1; }
  1291. static constexpr T Underflow() { return lowest(); }
  1292. };
  1293. TEST(SafeNumerics, CastTests) {
  1294. // MSVC catches and warns that we're forcing saturation in these tests.
  1295. // Since that's intentional, we need to shut this warning off.
  1296. #if defined(COMPILER_MSVC)
  1297. #pragma warning(disable : 4756)
  1298. #endif
  1299. int small_positive = 1;
  1300. int small_negative = -1;
  1301. double double_small = 1.0;
  1302. double double_large = numeric_limits<double>::max();
  1303. double double_infinity = numeric_limits<float>::infinity();
  1304. double double_large_int = numeric_limits<int>::max();
  1305. double double_small_int = numeric_limits<int>::lowest();
  1306. // Just test that the casts compile, since the other tests cover logic.
  1307. EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
  1308. EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
  1309. EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
  1310. EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
  1311. EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
  1312. EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
  1313. EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
  1314. EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
  1315. EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
  1316. EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
  1317. EXPECT_TRUE(IsValueNegative(-1));
  1318. EXPECT_TRUE(IsValueNegative(numeric_limits<int>::lowest()));
  1319. EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::lowest()));
  1320. EXPECT_TRUE(IsValueNegative(numeric_limits<double>::lowest()));
  1321. EXPECT_FALSE(IsValueNegative(0));
  1322. EXPECT_FALSE(IsValueNegative(1));
  1323. EXPECT_FALSE(IsValueNegative(0u));
  1324. EXPECT_FALSE(IsValueNegative(1u));
  1325. EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
  1326. EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
  1327. EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
  1328. // These casts and coercions will fail to compile:
  1329. // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
  1330. // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
  1331. // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
  1332. // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
  1333. // Test various saturation corner cases.
  1334. EXPECT_EQ(saturated_cast<int>(small_negative),
  1335. static_cast<int>(small_negative));
  1336. EXPECT_EQ(saturated_cast<int>(small_positive),
  1337. static_cast<int>(small_positive));
  1338. EXPECT_EQ(saturated_cast<unsigned>(small_negative), static_cast<unsigned>(0));
  1339. EXPECT_EQ(saturated_cast<int>(double_small), static_cast<int>(double_small));
  1340. EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
  1341. EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
  1342. EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
  1343. EXPECT_EQ(numeric_limits<int>::lowest(),
  1344. saturated_cast<int>(double_small_int));
  1345. EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
  1346. // Test the saturated cast overrides.
  1347. using FloatLimits = numeric_limits<float>;
  1348. using IntLimits = numeric_limits<int>;
  1349. EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(FloatLimits::quiet_NaN())));
  1350. EXPECT_EQ(CastTest1<int>::max(),
  1351. (saturated_cast<int, CastTest1>(FloatLimits::infinity())));
  1352. EXPECT_EQ(CastTest1<int>::max(),
  1353. (saturated_cast<int, CastTest1>(FloatLimits::max())));
  1354. EXPECT_EQ(CastTest1<int>::max(),
  1355. (saturated_cast<int, CastTest1>(float(IntLimits::max()))));
  1356. EXPECT_EQ(CastTest1<int>::lowest(),
  1357. (saturated_cast<int, CastTest1>(-FloatLimits::infinity())));
  1358. EXPECT_EQ(CastTest1<int>::lowest(),
  1359. (saturated_cast<int, CastTest1>(FloatLimits::lowest())));
  1360. EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0.0)));
  1361. EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1.0)));
  1362. EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1.0)));
  1363. EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0)));
  1364. EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1)));
  1365. EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1)));
  1366. EXPECT_EQ(CastTest1<int>::lowest(),
  1367. (saturated_cast<int, CastTest1>(float(IntLimits::lowest()))));
  1368. EXPECT_EQ(11, (saturated_cast<int, CastTest2>(FloatLimits::quiet_NaN())));
  1369. EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::infinity())));
  1370. EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::max())));
  1371. EXPECT_EQ(1, (saturated_cast<int, CastTest2>(-FloatLimits::infinity())));
  1372. EXPECT_EQ(1, (saturated_cast<int, CastTest2>(FloatLimits::lowest())));
  1373. EXPECT_EQ(1, (saturated_cast<int, CastTest2>(0U)));
  1374. float not_a_number = std::numeric_limits<float>::infinity() -
  1375. std::numeric_limits<float>::infinity();
  1376. EXPECT_TRUE(std::isnan(not_a_number));
  1377. EXPECT_EQ(0, saturated_cast<int>(not_a_number));
  1378. // Test the CheckedNumeric value extractions functions.
  1379. auto int8_min = MakeCheckedNum(numeric_limits<int8_t>::lowest());
  1380. auto int8_max = MakeCheckedNum(numeric_limits<int8_t>::max());
  1381. auto double_max = MakeCheckedNum(numeric_limits<double>::max());
  1382. static_assert(
  1383. std::is_same<int16_t,
  1384. decltype(int8_min.ValueOrDie<int16_t>())::type>::value,
  1385. "ValueOrDie returning incorrect type.");
  1386. static_assert(
  1387. std::is_same<int16_t,
  1388. decltype(int8_min.ValueOrDefault<int16_t>(0))::type>::value,
  1389. "ValueOrDefault returning incorrect type.");
  1390. EXPECT_FALSE(IsValidForType<uint8_t>(int8_min));
  1391. EXPECT_TRUE(IsValidForType<uint8_t>(int8_max));
  1392. EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::lowest()),
  1393. ValueOrDieForType<int>(int8_min));
  1394. EXPECT_TRUE(IsValidForType<uint32_t>(int8_max));
  1395. EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::max()),
  1396. ValueOrDieForType<int>(int8_max));
  1397. EXPECT_EQ(0, ValueOrDefaultForType<int>(double_max, 0));
  1398. uint8_t uint8_dest = 0;
  1399. int16_t int16_dest = 0;
  1400. double double_dest = 0;
  1401. EXPECT_TRUE(int8_max.AssignIfValid(&uint8_dest));
  1402. EXPECT_EQ(static_cast<uint8_t>(numeric_limits<int8_t>::max()), uint8_dest);
  1403. EXPECT_FALSE(int8_min.AssignIfValid(&uint8_dest));
  1404. EXPECT_TRUE(int8_max.AssignIfValid(&int16_dest));
  1405. EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::max()), int16_dest);
  1406. EXPECT_TRUE(int8_min.AssignIfValid(&int16_dest));
  1407. EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::lowest()), int16_dest);
  1408. EXPECT_FALSE(double_max.AssignIfValid(&uint8_dest));
  1409. EXPECT_FALSE(double_max.AssignIfValid(&int16_dest));
  1410. EXPECT_TRUE(double_max.AssignIfValid(&double_dest));
  1411. EXPECT_EQ(numeric_limits<double>::max(), double_dest);
  1412. EXPECT_EQ(1, checked_cast<int>(StrictNumeric<int>(1)));
  1413. EXPECT_EQ(1, saturated_cast<int>(StrictNumeric<int>(1)));
  1414. EXPECT_EQ(1, strict_cast<int>(StrictNumeric<int>(1)));
  1415. enum class EnumTest { kOne = 1 };
  1416. EXPECT_EQ(1, checked_cast<int>(EnumTest::kOne));
  1417. EXPECT_EQ(1, saturated_cast<int>(EnumTest::kOne));
  1418. EXPECT_EQ(1, strict_cast<int>(EnumTest::kOne));
  1419. }
  1420. TEST(SafeNumerics, IsValueInRangeForNumericType) {
  1421. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
  1422. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
  1423. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
  1424. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
  1425. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
  1426. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
  1427. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
  1428. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
  1429. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
  1430. std::numeric_limits<int32_t>::lowest()));
  1431. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
  1432. std::numeric_limits<int64_t>::lowest()));
  1433. // Converting to integer types will discard the fractional part first, so -0.9
  1434. // will be truncated to -0.0.
  1435. EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(-0.9));
  1436. EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1.0));
  1437. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
  1438. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
  1439. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
  1440. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
  1441. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
  1442. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
  1443. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
  1444. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
  1445. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
  1446. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
  1447. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
  1448. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
  1449. std::numeric_limits<int32_t>::lowest()));
  1450. EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
  1451. static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
  1452. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
  1453. static_cast<int64_t>(std::numeric_limits<int32_t>::lowest()) - 1));
  1454. EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
  1455. std::numeric_limits<int64_t>::lowest()));
  1456. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
  1457. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
  1458. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
  1459. EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
  1460. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
  1461. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
  1462. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
  1463. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
  1464. EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
  1465. std::numeric_limits<int32_t>::lowest()));
  1466. EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
  1467. EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
  1468. std::numeric_limits<int64_t>::lowest()));
  1469. // Converting to integer types will discard the fractional part first, so -0.9
  1470. // will be truncated to -0.0.
  1471. EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(-0.9));
  1472. EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1.0));
  1473. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
  1474. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
  1475. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
  1476. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
  1477. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
  1478. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
  1479. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
  1480. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
  1481. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
  1482. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
  1483. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
  1484. EXPECT_TRUE(
  1485. IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
  1486. EXPECT_TRUE(
  1487. IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
  1488. EXPECT_FALSE(
  1489. IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
  1490. EXPECT_FALSE(
  1491. IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
  1492. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
  1493. std::numeric_limits<int32_t>::lowest()));
  1494. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
  1495. static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
  1496. EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
  1497. std::numeric_limits<int64_t>::lowest()));
  1498. }
  1499. TEST(SafeNumerics, CompoundNumericOperations) {
  1500. CheckedNumeric<int> a = 1;
  1501. CheckedNumeric<int> b = 2;
  1502. CheckedNumeric<int> c = 3;
  1503. CheckedNumeric<int> d = 4;
  1504. a += b;
  1505. EXPECT_EQ(3, a.ValueOrDie());
  1506. a -= c;
  1507. EXPECT_EQ(0, a.ValueOrDie());
  1508. d /= b;
  1509. EXPECT_EQ(2, d.ValueOrDie());
  1510. d *= d;
  1511. EXPECT_EQ(4, d.ValueOrDie());
  1512. d *= 0.5;
  1513. EXPECT_EQ(2, d.ValueOrDie());
  1514. CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
  1515. EXPECT_TRUE(too_large.IsValid());
  1516. too_large += d;
  1517. EXPECT_FALSE(too_large.IsValid());
  1518. too_large -= d;
  1519. EXPECT_FALSE(too_large.IsValid());
  1520. too_large /= d;
  1521. EXPECT_FALSE(too_large.IsValid());
  1522. }
  1523. TEST(SafeNumerics, VariadicNumericOperations) {
  1524. { // Synthetic scope to avoid variable naming collisions.
  1525. auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie();
  1526. EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
  1527. auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie();
  1528. EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
  1529. auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie();
  1530. EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
  1531. auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie();
  1532. EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
  1533. auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie();
  1534. EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
  1535. auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie();
  1536. EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
  1537. auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie();
  1538. EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
  1539. auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie();
  1540. EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
  1541. }
  1542. {
  1543. auto a = ClampAdd(1, 2UL, MakeClampedNum(3LL), 4);
  1544. EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
  1545. auto b = ClampSub(MakeClampedNum(20.0), 2UL, 4);
  1546. EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
  1547. auto c = ClampMul(20.0, MakeClampedNum(1), 5, 3UL);
  1548. EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
  1549. auto d = ClampDiv(20.0, 2.0, MakeClampedNum(5LL), -4);
  1550. EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
  1551. auto e = ClampMod(MakeClampedNum(20), 3);
  1552. EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
  1553. auto f = ClampLsh(1, MakeClampedNum(2U));
  1554. EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
  1555. auto g = ClampRsh(4, MakeClampedNum(2U));
  1556. EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
  1557. auto h = ClampRsh(ClampAdd(1, 1, 1, 1), ClampSub(4U, 2));
  1558. EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
  1559. }
  1560. }
  1561. TEST(SafeNumerics, CeilInt) {
  1562. constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
  1563. constexpr float kMin = std::numeric_limits<int>::min();
  1564. constexpr float kInfinity = std::numeric_limits<float>::infinity();
  1565. constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
  1566. constexpr int kIntMax = std::numeric_limits<int>::max();
  1567. constexpr int kIntMin = std::numeric_limits<int>::min();
  1568. EXPECT_EQ(kIntMax, ClampCeil(kInfinity));
  1569. EXPECT_EQ(kIntMax, ClampCeil(kMax));
  1570. EXPECT_EQ(kIntMax, ClampCeil(kMax + 100.0f));
  1571. EXPECT_EQ(0, ClampCeil(kNaN));
  1572. EXPECT_EQ(-100, ClampCeil(-100.5f));
  1573. EXPECT_EQ(0, ClampCeil(0.0f));
  1574. EXPECT_EQ(101, ClampCeil(100.5f));
  1575. EXPECT_EQ(kIntMin, ClampCeil(-kInfinity));
  1576. EXPECT_EQ(kIntMin, ClampCeil(kMin));
  1577. EXPECT_EQ(kIntMin, ClampCeil(kMin - 100.0f));
  1578. EXPECT_EQ(0, ClampCeil(-kNaN));
  1579. }
  1580. TEST(SafeNumerics, FloorInt) {
  1581. constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
  1582. constexpr float kMin = std::numeric_limits<int>::min();
  1583. constexpr float kInfinity = std::numeric_limits<float>::infinity();
  1584. constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
  1585. constexpr int kIntMax = std::numeric_limits<int>::max();
  1586. constexpr int kIntMin = std::numeric_limits<int>::min();
  1587. EXPECT_EQ(kIntMax, ClampFloor(kInfinity));
  1588. EXPECT_EQ(kIntMax, ClampFloor(kMax));
  1589. EXPECT_EQ(kIntMax, ClampFloor(kMax + 100.0f));
  1590. EXPECT_EQ(0, ClampFloor(kNaN));
  1591. EXPECT_EQ(-101, ClampFloor(-100.5f));
  1592. EXPECT_EQ(0, ClampFloor(0.0f));
  1593. EXPECT_EQ(100, ClampFloor(100.5f));
  1594. EXPECT_EQ(kIntMin, ClampFloor(-kInfinity));
  1595. EXPECT_EQ(kIntMin, ClampFloor(kMin));
  1596. EXPECT_EQ(kIntMin, ClampFloor(kMin - 100.0f));
  1597. EXPECT_EQ(0, ClampFloor(-kNaN));
  1598. }
  1599. TEST(SafeNumerics, RoundInt) {
  1600. constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
  1601. constexpr float kMin = std::numeric_limits<int>::min();
  1602. constexpr float kInfinity = std::numeric_limits<float>::infinity();
  1603. constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
  1604. constexpr int kIntMax = std::numeric_limits<int>::max();
  1605. constexpr int kIntMin = std::numeric_limits<int>::min();
  1606. EXPECT_EQ(kIntMax, ClampRound(kInfinity));
  1607. EXPECT_EQ(kIntMax, ClampRound(kMax));
  1608. EXPECT_EQ(kIntMax, ClampRound(kMax + 100.0f));
  1609. EXPECT_EQ(0, ClampRound(kNaN));
  1610. EXPECT_EQ(-100, ClampRound(-100.1f));
  1611. EXPECT_EQ(-101, ClampRound(-100.5f));
  1612. EXPECT_EQ(-101, ClampRound(-100.9f));
  1613. EXPECT_EQ(0, ClampRound(0.0f));
  1614. EXPECT_EQ(100, ClampRound(100.1f));
  1615. EXPECT_EQ(101, ClampRound(100.5f));
  1616. EXPECT_EQ(101, ClampRound(100.9f));
  1617. EXPECT_EQ(kIntMin, ClampRound(-kInfinity));
  1618. EXPECT_EQ(kIntMin, ClampRound(kMin));
  1619. EXPECT_EQ(kIntMin, ClampRound(kMin - 100.0f));
  1620. EXPECT_EQ(0, ClampRound(-kNaN));
  1621. }
  1622. TEST(SafeNumerics, Int64) {
  1623. constexpr double kMax =
  1624. static_cast<double>(std::numeric_limits<int64_t>::max());
  1625. constexpr double kMin = std::numeric_limits<int64_t>::min();
  1626. constexpr double kInfinity = std::numeric_limits<double>::infinity();
  1627. constexpr double kNaN = std::numeric_limits<double>::quiet_NaN();
  1628. constexpr int64_t kInt64Max = std::numeric_limits<int64_t>::max();
  1629. constexpr int64_t kInt64Min = std::numeric_limits<int64_t>::min();
  1630. EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kInfinity));
  1631. EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kInfinity));
  1632. EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kInfinity));
  1633. EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax));
  1634. EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax));
  1635. EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax));
  1636. EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax + 100.0));
  1637. EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax + 100.0));
  1638. EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax + 100.0));
  1639. EXPECT_EQ(0, ClampFloor<int64_t>(kNaN));
  1640. EXPECT_EQ(0, ClampCeil<int64_t>(kNaN));
  1641. EXPECT_EQ(0, ClampRound<int64_t>(kNaN));
  1642. EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(-kInfinity));
  1643. EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(-kInfinity));
  1644. EXPECT_EQ(kInt64Min, ClampRound<int64_t>(-kInfinity));
  1645. EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin));
  1646. EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin));
  1647. EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin));
  1648. EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin - 100.0));
  1649. EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin - 100.0));
  1650. EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin - 100.0));
  1651. EXPECT_EQ(0, ClampFloor<int64_t>(-kNaN));
  1652. EXPECT_EQ(0, ClampCeil<int64_t>(-kNaN));
  1653. EXPECT_EQ(0, ClampRound<int64_t>(-kNaN));
  1654. }
  1655. #if defined(__clang__)
  1656. #pragma clang diagnostic pop // -Winteger-overflow
  1657. #endif
  1658. } // namespace internal
  1659. } // namespace base