Blame lib/xalloc-oversized.h

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