return result;
}
+#ifndef SIZE_MAX
+# include <limits.h>
+#endif
+#ifdef SIZE_MAX
+# define AO_SIZE_MAX SIZE_MAX
+#else
+# define AO_SIZE_MAX (~(size_t)0)
+#endif
+
+/* Saturated addition of size_t values. Used to avoid value wrap */
+/* around on overflow. The arguments should have no side effects. */
+#define SIZET_SAT_ADD(a, b) \
+ ((a) < AO_SIZE_MAX - (b) ? (a) + (b) : AO_SIZE_MAX)
+
/* Allocate an object of size (incl. header) of size > CHUNK_SIZE. */
/* sz includes space for an AO_t-sized header. */
static char *
{
char * result;
/* The header will force us to waste ALIGNMENT bytes, incl. header. */
- sz += ALIGNMENT;
- /* Round to multiple of CHUNK_SIZE. */
- sz = (sz + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
+ /* Round to multiple of CHUNK_SIZE. */
+ sz = SIZET_SAT_ADD(sz, ALIGNMENT + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);
result = get_mmaped(sz);
if (result == 0) return 0;
result += ALIGNMENT;