Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
int.h442 linesDownload Raw Back to common
1/*-------------------------------------------------------------------------2 *3 * int.h4 *	  Routines to perform integer math, while checking for overflows.5 *6 * The routines in this file are intended to be well defined C, without7 * relying on compiler flags like -fwrapv.8 *9 * To reduce the overhead of these routines try to use compiler intrinsics10 * where available. That's not that important for the 16, 32 bit cases, but11 * the 64 bit cases can be considerably faster with intrinsics. In case no12 * intrinsics are available 128 bit math is used where available.13 *14 * Copyright (c) 2017-2023, PostgreSQL Global Development Group15 *16 * src/include/common/int.h17 *18 *-------------------------------------------------------------------------19 */20#ifndef COMMON_INT_H21#define COMMON_INT_H22 23 24/*---------25 * The following guidelines apply to all the routines:26 * - If a + b overflows, return true, otherwise store the result of a + b27 * into *result. The content of *result is implementation defined in case of28 * overflow.29 * - If a - b overflows, return true, otherwise store the result of a - b30 * into *result. The content of *result is implementation defined in case of31 * overflow.32 * - If a * b overflows, return true, otherwise store the result of a * b33 * into *result. The content of *result is implementation defined in case of34 * overflow.35 *---------36 */37 38/*------------------------------------------------------------------------39 * Overflow routines for signed integers40 *------------------------------------------------------------------------41 */42 43/*44 * INT1645 */46static inline bool47pg_add_s16_overflow(int16 a, int16 b, int16 *result)48{49#if defined(HAVE__BUILTIN_OP_OVERFLOW)50	return __builtin_add_overflow(a, b, result);51#else52	int32		res = (int32) a + (int32) b;53 54	if (res > PG_INT16_MAX || res < PG_INT16_MIN)55	{56		*result = 0x5EED;		/* to avoid spurious warnings */57		return true;58	}59	*result = (int16) res;60	return false;61#endif62}63 64static inline bool65pg_sub_s16_overflow(int16 a, int16 b, int16 *result)66{67#if defined(HAVE__BUILTIN_OP_OVERFLOW)68	return __builtin_sub_overflow(a, b, result);69#else70	int32		res = (int32) a - (int32) b;71 72	if (res > PG_INT16_MAX || res < PG_INT16_MIN)73	{74		*result = 0x5EED;		/* to avoid spurious warnings */75		return true;76	}77	*result = (int16) res;78	return false;79#endif80}81 82static inline bool83pg_mul_s16_overflow(int16 a, int16 b, int16 *result)84{85#if defined(HAVE__BUILTIN_OP_OVERFLOW)86	return __builtin_mul_overflow(a, b, result);87#else88	int32		res = (int32) a * (int32) b;89 90	if (res > PG_INT16_MAX || res < PG_INT16_MIN)91	{92		*result = 0x5EED;		/* to avoid spurious warnings */93		return true;94	}95	*result = (int16) res;96	return false;97#endif98}99 100/*101 * INT32102 */103static inline bool104pg_add_s32_overflow(int32 a, int32 b, int32 *result)105{106#if defined(HAVE__BUILTIN_OP_OVERFLOW)107	return __builtin_add_overflow(a, b, result);108#else109	int64		res = (int64) a + (int64) b;110 111	if (res > PG_INT32_MAX || res < PG_INT32_MIN)112	{113		*result = 0x5EED;		/* to avoid spurious warnings */114		return true;115	}116	*result = (int32) res;117	return false;118#endif119}120 121static inline bool122pg_sub_s32_overflow(int32 a, int32 b, int32 *result)123{124#if defined(HAVE__BUILTIN_OP_OVERFLOW)125	return __builtin_sub_overflow(a, b, result);126#else127	int64		res = (int64) a - (int64) b;128 129	if (res > PG_INT32_MAX || res < PG_INT32_MIN)130	{131		*result = 0x5EED;		/* to avoid spurious warnings */132		return true;133	}134	*result = (int32) res;135	return false;136#endif137}138 139static inline bool140pg_mul_s32_overflow(int32 a, int32 b, int32 *result)141{142#if defined(HAVE__BUILTIN_OP_OVERFLOW)143	return __builtin_mul_overflow(a, b, result);144#else145	int64		res = (int64) a * (int64) b;146 147	if (res > PG_INT32_MAX || res < PG_INT32_MIN)148	{149		*result = 0x5EED;		/* to avoid spurious warnings */150		return true;151	}152	*result = (int32) res;153	return false;154#endif155}156 157/*158 * INT64159 */160static inline bool161pg_add_s64_overflow(int64 a, int64 b, int64 *result)162{163#if defined(HAVE__BUILTIN_OP_OVERFLOW)164	return __builtin_add_overflow(a, b, result);165#elif defined(HAVE_INT128)166	int128		res = (int128) a + (int128) b;167 168	if (res > PG_INT64_MAX || res < PG_INT64_MIN)169	{170		*result = 0x5EED;		/* to avoid spurious warnings */171		return true;172	}173	*result = (int64) res;174	return false;175#else176	if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||177		(a < 0 && b < 0 && a < PG_INT64_MIN - b))178	{179		*result = 0x5EED;		/* to avoid spurious warnings */180		return true;181	}182	*result = a + b;183	return false;184#endif185}186 187static inline bool188pg_sub_s64_overflow(int64 a, int64 b, int64 *result)189{190#if defined(HAVE__BUILTIN_OP_OVERFLOW)191	return __builtin_sub_overflow(a, b, result);192#elif defined(HAVE_INT128)193	int128		res = (int128) a - (int128) b;194 195	if (res > PG_INT64_MAX || res < PG_INT64_MIN)196	{197		*result = 0x5EED;		/* to avoid spurious warnings */198		return true;199	}200	*result = (int64) res;201	return false;202#else203	/*204	 * Note: overflow is also possible when a == 0 and b < 0 (specifically,205	 * when b == PG_INT64_MIN).206	 */207	if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||208		(a >= 0 && b < 0 && a > PG_INT64_MAX + b))209	{210		*result = 0x5EED;		/* to avoid spurious warnings */211		return true;212	}213	*result = a - b;214	return false;215#endif216}217 218static inline bool219pg_mul_s64_overflow(int64 a, int64 b, int64 *result)220{221#if defined(HAVE__BUILTIN_OP_OVERFLOW)222	return __builtin_mul_overflow(a, b, result);223#elif defined(HAVE_INT128)224	int128		res = (int128) a * (int128) b;225 226	if (res > PG_INT64_MAX || res < PG_INT64_MIN)227	{228		*result = 0x5EED;		/* to avoid spurious warnings */229		return true;230	}231	*result = (int64) res;232	return false;233#else234	/*235	 * Overflow can only happen if at least one value is outside the range236	 * sqrt(min)..sqrt(max) so check that first as the division can be quite a237	 * bit more expensive than the multiplication.238	 *239	 * Multiplying by 0 or 1 can't overflow of course and checking for 0240	 * separately avoids any risk of dividing by 0.  Be careful about dividing241	 * INT_MIN by -1 also, note reversing the a and b to ensure we're always242	 * dividing it by a positive value.243	 *244	 */245	if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||246		 b > PG_INT32_MAX || b < PG_INT32_MIN) &&247		a != 0 && a != 1 && b != 0 && b != 1 &&248		((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||249		 (a > 0 && b < 0 && b < PG_INT64_MIN / a) ||250		 (a < 0 && b > 0 && a < PG_INT64_MIN / b) ||251		 (a < 0 && b < 0 && a < PG_INT64_MAX / b)))252	{253		*result = 0x5EED;		/* to avoid spurious warnings */254		return true;255	}256	*result = a * b;257	return false;258#endif259}260 261/*------------------------------------------------------------------------262 * Overflow routines for unsigned integers263 *------------------------------------------------------------------------264 */265 266/*267 * UINT16268 */269static inline bool270pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result)271{272#if defined(HAVE__BUILTIN_OP_OVERFLOW)273	return __builtin_add_overflow(a, b, result);274#else275	uint16		res = a + b;276 277	if (res < a)278	{279		*result = 0x5EED;		/* to avoid spurious warnings */280		return true;281	}282	*result = res;283	return false;284#endif285}286 287static inline bool288pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result)289{290#if defined(HAVE__BUILTIN_OP_OVERFLOW)291	return __builtin_sub_overflow(a, b, result);292#else293	if (b > a)294	{295		*result = 0x5EED;		/* to avoid spurious warnings */296		return true;297	}298	*result = a - b;299	return false;300#endif301}302 303static inline bool304pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result)305{306#if defined(HAVE__BUILTIN_OP_OVERFLOW)307	return __builtin_mul_overflow(a, b, result);308#else309	uint32		res = (uint32) a * (uint32) b;310 311	if (res > PG_UINT16_MAX)312	{313		*result = 0x5EED;		/* to avoid spurious warnings */314		return true;315	}316	*result = (uint16) res;317	return false;318#endif319}320 321/*322 * INT32323 */324static inline bool325pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result)326{327#if defined(HAVE__BUILTIN_OP_OVERFLOW)328	return __builtin_add_overflow(a, b, result);329#else330	uint32		res = a + b;331 332	if (res < a)333	{334		*result = 0x5EED;		/* to avoid spurious warnings */335		return true;336	}337	*result = res;338	return false;339#endif340}341 342static inline bool343pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result)344{345#if defined(HAVE__BUILTIN_OP_OVERFLOW)346	return __builtin_sub_overflow(a, b, result);347#else348	if (b > a)349	{350		*result = 0x5EED;		/* to avoid spurious warnings */351		return true;352	}353	*result = a - b;354	return false;355#endif356}357 358static inline bool359pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result)360{361#if defined(HAVE__BUILTIN_OP_OVERFLOW)362	return __builtin_mul_overflow(a, b, result);363#else364	uint64		res = (uint64) a * (uint64) b;365 366	if (res > PG_UINT32_MAX)367	{368		*result = 0x5EED;		/* to avoid spurious warnings */369		return true;370	}371	*result = (uint32) res;372	return false;373#endif374}375 376/*377 * UINT64378 */379static inline bool380pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)381{382#if defined(HAVE__BUILTIN_OP_OVERFLOW)383	return __builtin_add_overflow(a, b, result);384#else385	uint64		res = a + b;386 387	if (res < a)388	{389		*result = 0x5EED;		/* to avoid spurious warnings */390		return true;391	}392	*result = res;393	return false;394#endif395}396 397static inline bool398pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)399{400#if defined(HAVE__BUILTIN_OP_OVERFLOW)401	return __builtin_sub_overflow(a, b, result);402#else403	if (b > a)404	{405		*result = 0x5EED;		/* to avoid spurious warnings */406		return true;407	}408	*result = a - b;409	return false;410#endif411}412 413static inline bool414pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)415{416#if defined(HAVE__BUILTIN_OP_OVERFLOW)417	return __builtin_mul_overflow(a, b, result);418#elif defined(HAVE_INT128)419	uint128		res = (uint128) a * (uint128) b;420 421	if (res > PG_UINT64_MAX)422	{423		*result = 0x5EED;		/* to avoid spurious warnings */424		return true;425	}426	*result = (uint64) res;427	return false;428#else429	uint64		res = a * b;430 431	if (a != 0 && b != res / a)432	{433		*result = 0x5EED;		/* to avoid spurious warnings */434		return true;435	}436	*result = res;437	return false;438#endif439}440 441#endif							/* COMMON_INT_H */442 
codekingpro/portable-devtools · Team Ai