Blame lib/xalloc-oversized.h

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