2
0

int.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*-------------------------------------------------------------------------
  2. *
  3. * int.h
  4. * Routines to perform integer math, while checking for overflows.
  5. *
  6. * The routines in this file are intended to be well defined C, without
  7. * relying on compiler flags like -fwrapv.
  8. *
  9. * To reduce the overhead of these routines try to use compiler intrinsics
  10. * where available. That's not that important for the 16, 32 bit cases, but
  11. * the 64 bit cases can be considerably faster with intrinsics. In case no
  12. * intrinsics are available 128 bit math is used where available.
  13. *
  14. * Copyright (c) 2017-2022, PostgreSQL Global Development Group
  15. *
  16. * src/include/common/int.h
  17. *
  18. *-------------------------------------------------------------------------
  19. */
  20. #ifndef COMMON_INT_H
  21. #define COMMON_INT_H
  22. /*---------
  23. * The following guidelines apply to all the routines:
  24. * - If a + b overflows, return true, otherwise store the result of a + b
  25. * into *result. The content of *result is implementation defined in case of
  26. * overflow.
  27. * - If a - b overflows, return true, otherwise store the result of a - b
  28. * into *result. The content of *result is implementation defined in case of
  29. * overflow.
  30. * - If a * b overflows, return true, otherwise store the result of a * b
  31. * into *result. The content of *result is implementation defined in case of
  32. * overflow.
  33. *---------
  34. */
  35. /*------------------------------------------------------------------------
  36. * Overflow routines for signed integers
  37. *------------------------------------------------------------------------
  38. */
  39. /*
  40. * INT16
  41. */
  42. static inline bool
  43. pg_add_s16_overflow(int16 a, int16 b, int16 *result)
  44. {
  45. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  46. return __builtin_add_overflow(a, b, result);
  47. #else
  48. int32 res = (int32) a + (int32) b;
  49. if (res > PG_INT16_MAX || res < PG_INT16_MIN)
  50. {
  51. *result = 0x5EED; /* to avoid spurious warnings */
  52. return true;
  53. }
  54. *result = (int16) res;
  55. return false;
  56. #endif
  57. }
  58. static inline bool
  59. pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
  60. {
  61. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  62. return __builtin_sub_overflow(a, b, result);
  63. #else
  64. int32 res = (int32) a - (int32) b;
  65. if (res > PG_INT16_MAX || res < PG_INT16_MIN)
  66. {
  67. *result = 0x5EED; /* to avoid spurious warnings */
  68. return true;
  69. }
  70. *result = (int16) res;
  71. return false;
  72. #endif
  73. }
  74. static inline bool
  75. pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
  76. {
  77. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  78. return __builtin_mul_overflow(a, b, result);
  79. #else
  80. int32 res = (int32) a * (int32) b;
  81. if (res > PG_INT16_MAX || res < PG_INT16_MIN)
  82. {
  83. *result = 0x5EED; /* to avoid spurious warnings */
  84. return true;
  85. }
  86. *result = (int16) res;
  87. return false;
  88. #endif
  89. }
  90. /*
  91. * INT32
  92. */
  93. static inline bool
  94. pg_add_s32_overflow(int32 a, int32 b, int32 *result)
  95. {
  96. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  97. return __builtin_add_overflow(a, b, result);
  98. #else
  99. int64 res = (int64) a + (int64) b;
  100. if (res > PG_INT32_MAX || res < PG_INT32_MIN)
  101. {
  102. *result = 0x5EED; /* to avoid spurious warnings */
  103. return true;
  104. }
  105. *result = (int32) res;
  106. return false;
  107. #endif
  108. }
  109. static inline bool
  110. pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
  111. {
  112. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  113. return __builtin_sub_overflow(a, b, result);
  114. #else
  115. int64 res = (int64) a - (int64) b;
  116. if (res > PG_INT32_MAX || res < PG_INT32_MIN)
  117. {
  118. *result = 0x5EED; /* to avoid spurious warnings */
  119. return true;
  120. }
  121. *result = (int32) res;
  122. return false;
  123. #endif
  124. }
  125. static inline bool
  126. pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
  127. {
  128. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  129. return __builtin_mul_overflow(a, b, result);
  130. #else
  131. int64 res = (int64) a * (int64) b;
  132. if (res > PG_INT32_MAX || res < PG_INT32_MIN)
  133. {
  134. *result = 0x5EED; /* to avoid spurious warnings */
  135. return true;
  136. }
  137. *result = (int32) res;
  138. return false;
  139. #endif
  140. }
  141. /*
  142. * INT64
  143. */
  144. static inline bool
  145. pg_add_s64_overflow(int64 a, int64 b, int64 *result)
  146. {
  147. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  148. return __builtin_add_overflow(a, b, result);
  149. #elif defined(HAVE_INT128)
  150. int128 res = (int128) a + (int128) b;
  151. if (res > PG_INT64_MAX || res < PG_INT64_MIN)
  152. {
  153. *result = 0x5EED; /* to avoid spurious warnings */
  154. return true;
  155. }
  156. *result = (int64) res;
  157. return false;
  158. #else
  159. if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
  160. (a < 0 && b < 0 && a < PG_INT64_MIN - b))
  161. {
  162. *result = 0x5EED; /* to avoid spurious warnings */
  163. return true;
  164. }
  165. *result = a + b;
  166. return false;
  167. #endif
  168. }
  169. static inline bool
  170. pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
  171. {
  172. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  173. return __builtin_sub_overflow(a, b, result);
  174. #elif defined(HAVE_INT128)
  175. int128 res = (int128) a - (int128) b;
  176. if (res > PG_INT64_MAX || res < PG_INT64_MIN)
  177. {
  178. *result = 0x5EED; /* to avoid spurious warnings */
  179. return true;
  180. }
  181. *result = (int64) res;
  182. return false;
  183. #else
  184. if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
  185. (a > 0 && b < 0 && a > PG_INT64_MAX + b))
  186. {
  187. *result = 0x5EED; /* to avoid spurious warnings */
  188. return true;
  189. }
  190. *result = a - b;
  191. return false;
  192. #endif
  193. }
  194. static inline bool
  195. pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
  196. {
  197. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  198. return __builtin_mul_overflow(a, b, result);
  199. #elif defined(HAVE_INT128)
  200. int128 res = (int128) a * (int128) b;
  201. if (res > PG_INT64_MAX || res < PG_INT64_MIN)
  202. {
  203. *result = 0x5EED; /* to avoid spurious warnings */
  204. return true;
  205. }
  206. *result = (int64) res;
  207. return false;
  208. #else
  209. /*
  210. * Overflow can only happen if at least one value is outside the range
  211. * sqrt(min)..sqrt(max) so check that first as the division can be quite a
  212. * bit more expensive than the multiplication.
  213. *
  214. * Multiplying by 0 or 1 can't overflow of course and checking for 0
  215. * separately avoids any risk of dividing by 0. Be careful about dividing
  216. * INT_MIN by -1 also, note reversing the a and b to ensure we're always
  217. * dividing it by a positive value.
  218. *
  219. */
  220. if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||
  221. b > PG_INT32_MAX || b < PG_INT32_MIN) &&
  222. a != 0 && a != 1 && b != 0 && b != 1 &&
  223. ((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||
  224. (a > 0 && b < 0 && b < PG_INT64_MIN / a) ||
  225. (a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
  226. (a < 0 && b < 0 && a < PG_INT64_MAX / b)))
  227. {
  228. *result = 0x5EED; /* to avoid spurious warnings */
  229. return true;
  230. }
  231. *result = a * b;
  232. return false;
  233. #endif
  234. }
  235. /*------------------------------------------------------------------------
  236. * Overflow routines for unsigned integers
  237. *------------------------------------------------------------------------
  238. */
  239. /*
  240. * UINT16
  241. */
  242. static inline bool
  243. pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result)
  244. {
  245. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  246. return __builtin_add_overflow(a, b, result);
  247. #else
  248. uint16 res = a + b;
  249. if (res < a)
  250. {
  251. *result = 0x5EED; /* to avoid spurious warnings */
  252. return true;
  253. }
  254. *result = res;
  255. return false;
  256. #endif
  257. }
  258. static inline bool
  259. pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result)
  260. {
  261. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  262. return __builtin_sub_overflow(a, b, result);
  263. #else
  264. if (b > a)
  265. {
  266. *result = 0x5EED; /* to avoid spurious warnings */
  267. return true;
  268. }
  269. *result = a - b;
  270. return false;
  271. #endif
  272. }
  273. static inline bool
  274. pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result)
  275. {
  276. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  277. return __builtin_mul_overflow(a, b, result);
  278. #else
  279. uint32 res = (uint32) a * (uint32) b;
  280. if (res > PG_UINT16_MAX)
  281. {
  282. *result = 0x5EED; /* to avoid spurious warnings */
  283. return true;
  284. }
  285. *result = (uint16) res;
  286. return false;
  287. #endif
  288. }
  289. /*
  290. * INT32
  291. */
  292. static inline bool
  293. pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result)
  294. {
  295. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  296. return __builtin_add_overflow(a, b, result);
  297. #else
  298. uint32 res = a + b;
  299. if (res < a)
  300. {
  301. *result = 0x5EED; /* to avoid spurious warnings */
  302. return true;
  303. }
  304. *result = res;
  305. return false;
  306. #endif
  307. }
  308. static inline bool
  309. pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result)
  310. {
  311. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  312. return __builtin_sub_overflow(a, b, result);
  313. #else
  314. if (b > a)
  315. {
  316. *result = 0x5EED; /* to avoid spurious warnings */
  317. return true;
  318. }
  319. *result = a - b;
  320. return false;
  321. #endif
  322. }
  323. static inline bool
  324. pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result)
  325. {
  326. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  327. return __builtin_mul_overflow(a, b, result);
  328. #else
  329. uint64 res = (uint64) a * (uint64) b;
  330. if (res > PG_UINT32_MAX)
  331. {
  332. *result = 0x5EED; /* to avoid spurious warnings */
  333. return true;
  334. }
  335. *result = (uint32) res;
  336. return false;
  337. #endif
  338. }
  339. /*
  340. * UINT64
  341. */
  342. static inline bool
  343. pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)
  344. {
  345. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  346. return __builtin_add_overflow(a, b, result);
  347. #else
  348. uint64 res = a + b;
  349. if (res < a)
  350. {
  351. *result = 0x5EED; /* to avoid spurious warnings */
  352. return true;
  353. }
  354. *result = res;
  355. return false;
  356. #endif
  357. }
  358. static inline bool
  359. pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)
  360. {
  361. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  362. return __builtin_sub_overflow(a, b, result);
  363. #else
  364. if (b > a)
  365. {
  366. *result = 0x5EED; /* to avoid spurious warnings */
  367. return true;
  368. }
  369. *result = a - b;
  370. return false;
  371. #endif
  372. }
  373. static inline bool
  374. pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
  375. {
  376. #if defined(HAVE__BUILTIN_OP_OVERFLOW)
  377. return __builtin_mul_overflow(a, b, result);
  378. #elif defined(HAVE_INT128)
  379. uint128 res = (uint128) a * (uint128) b;
  380. if (res > PG_UINT64_MAX)
  381. {
  382. *result = 0x5EED; /* to avoid spurious warnings */
  383. return true;
  384. }
  385. *result = (uint64) res;
  386. return false;
  387. #else
  388. uint64 res = a * b;
  389. if (a != 0 && b != res / a)
  390. {
  391. *result = 0x5EED; /* to avoid spurious warnings */
  392. return true;
  393. }
  394. *result = res;
  395. return false;
  396. #endif
  397. }
  398. #endif /* COMMON_INT_H */