Blame lib/xalloc-oversized.h

Packit Service fdd496
/* xalloc-oversized.h -- memory allocation size checking
Packit Service fdd496
Packit Service fdd496
   Copyright (C) 1990-2000, 2003-2004, 2006-2017 Free Software Foundation, Inc.
Packit Service fdd496
Packit Service fdd496
   This program is free software: you can redistribute it and/or modify
Packit Service fdd496
   it under the terms of the GNU General Public License as published by
Packit Service fdd496
   the Free Software Foundation; either version 3 of the License, or
Packit Service fdd496
   (at your option) any later version.
Packit Service fdd496
Packit Service fdd496
   This program is distributed in the hope that it will be useful,
Packit Service fdd496
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fdd496
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service fdd496
   GNU General Public License for more details.
Packit Service fdd496
Packit Service fdd496
   You should have received a copy of the GNU General Public License
Packit Service fdd496
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service fdd496
Packit Service fdd496
#ifndef XALLOC_OVERSIZED_H_
Packit Service fdd496
#define XALLOC_OVERSIZED_H_
Packit Service fdd496
Packit Service fdd496
#include <stddef.h>
Packit Service fdd496
#include <stdint.h>
Packit Service fdd496
Packit Service fdd496
/* True if N * S would overflow in a size_t calculation,
Packit Service fdd496
   or would generate a value larger than PTRDIFF_MAX.
Packit Service fdd496
   This expands to a constant expression if N and S are both constants.
Packit Service fdd496
   By gnulib convention, SIZE_MAX represents overflow in size
Packit Service fdd496
   calculations, so the conservative size_t-based dividend to use here
Packit Service fdd496
   is SIZE_MAX - 1.  */
Packit Service fdd496
#define __xalloc_oversized(n, s) \
Packit Service fdd496
  ((size_t) (PTRDIFF_MAX < SIZE_MAX ? PTRDIFF_MAX : SIZE_MAX - 1) / (s) < (n))
Packit Service fdd496
Packit Service fdd496
#if PTRDIFF_MAX < SIZE_MAX
Packit Service fdd496
typedef ptrdiff_t __xalloc_count_type;
Packit Service fdd496
#else
Packit Service fdd496
typedef size_t __xalloc_count_type;
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
/* Return 1 if an array of N objects, each of size S, cannot exist
Packit Service fdd496
   reliably due to size or ptrdiff_t arithmetic overflow.  S must be
Packit Service fdd496
   positive and N must be nonnegative.  This is a macro, not a
Packit Service fdd496
   function, so that it works correctly even when SIZE_MAX < N.  */
Packit Service fdd496
Packit Service fdd496
#if 7 <= __GNUC__
Packit Service fdd496
# define xalloc_oversized(n, s) \
Packit Service fdd496
   __builtin_mul_overflow_p (n, s, (__xalloc_count_type) 1)
Packit Service fdd496
#elif 5 <= __GNUC__ && !__STRICT_ANSI__
Packit Service fdd496
# define xalloc_oversized(n, s) \
Packit Service fdd496
   (__builtin_constant_p (n) && __builtin_constant_p (s) \
Packit Service fdd496
    ? __xalloc_oversized (n, s) \
Packit Service fdd496
    : ({ __xalloc_count_type __xalloc_count; \
Packit Service fdd496
         __builtin_mul_overflow (n, s, &__xalloc_count); }))
Packit Service fdd496
Packit Service fdd496
/* Other compilers use integer division; this may be slower but is
Packit Service fdd496
   more portable.  */
Packit Service fdd496
#else
Packit Service fdd496
# define xalloc_oversized(n, s) __xalloc_oversized (n, s)
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
#endif /* !XALLOC_OVERSIZED_H_ */