* src/xdisp.c (string_from_display_spec): Simplify.
[emacs.git] / lib / xalloc-oversized.h
blob503bb37801b22d50b703e6db0d47d1f9834c0610
1 /* xalloc-oversized.h -- memory allocation size checking
3 Copyright (C) 1990-2000, 2003-2004, 2006-2016 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #ifndef XALLOC_OVERSIZED_H_
19 #define XALLOC_OVERSIZED_H_
21 #include <stddef.h>
22 #include <stdint.h>
24 /* Default for (non-Clang) compilers that lack __has_builtin. */
25 #ifndef __has_builtin
26 # define __has_builtin(x) 0
27 #endif
29 /* True if N * S would overflow in a size_t calculation,
30 or would generate a value larger than PTRDIFF_MAX.
31 This expands to a constant expression if N and S are both constants.
32 By gnulib convention, SIZE_MAX represents overflow in size
33 calculations, so the conservative size_t-based dividend to use here
34 is SIZE_MAX - 1. */
35 #define __xalloc_oversized(n, s) \
36 ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
38 #if PTRDIFF_MAX < SIZE_MAX
39 typedef ptrdiff_t __xalloc_count_type;
40 #else
41 typedef size_t __xalloc_count_type;
42 #endif
44 /* Return 1 if an array of N objects, each of size S, cannot exist
45 reliably due to size or ptrdiff_t arithmetic overflow. S must be
46 positive and N must be nonnegative. This is a macro, not a
47 function, so that it works correctly even when SIZE_MAX < N. */
49 #if 7 <= __GNUC__ || __has_builtin (__builtin_add_overflow_p)
50 # define xalloc_oversized(n, s) \
51 __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
52 #elif ((5 <= __GNUC__ \
53 || (__has_builtin (__builtin_mul_overflow) \
54 && __has_builtin (__builtin_constant_p))) \
55 && !__STRICT_ANSI__)
56 # define xalloc_oversized(n, s) \
57 (__builtin_constant_p (n) && __builtin_constant_p (s) \
58 ? __xalloc_oversized (n, s) \
59 : ({ __xalloc_count_type __xalloc_count; \
60 __builtin_mul_overflow (n, s, &__xalloc_count); }))
62 /* Other compilers use integer division; this may be slower but is
63 more portable. */
64 #else
65 # define xalloc_oversized(n, s) __xalloc_oversized (n, s)
66 #endif
68 #endif /* !XALLOC_OVERSIZED_H_ */