Blame gnulib/lib/malloca.h

Packit Service 51e54d
/* Safe automatic memory allocation.
Packit Service 51e54d
   Copyright (C) 2003-2007, 2009-2014 Free Software Foundation, Inc.
Packit Service 51e54d
   Written by Bruno Haible <bruno@clisp.org>, 2003.
Packit Service 51e54d
Packit Service 51e54d
   This program is free software; you can redistribute it and/or modify
Packit Service 51e54d
   it under the terms of the GNU General Public License as published by
Packit Service 51e54d
   the Free Software Foundation; either version 3, or (at your option)
Packit Service 51e54d
   any later version.
Packit Service 51e54d
Packit Service 51e54d
   This program is distributed in the hope that it will be useful,
Packit Service 51e54d
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 51e54d
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 51e54d
   GNU General Public License for more details.
Packit Service 51e54d
Packit Service 51e54d
   You should have received a copy of the GNU General Public License
Packit Service 51e54d
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit Service 51e54d
Packit Service 51e54d
#ifndef _MALLOCA_H
Packit Service 51e54d
#define _MALLOCA_H
Packit Service 51e54d
Packit Service 51e54d
#include <alloca.h>
Packit Service 51e54d
#include <stddef.h>
Packit Service 51e54d
#include <stdlib.h>
Packit Service 51e54d
Packit Service 51e54d
Packit Service 51e54d
#ifdef __cplusplus
Packit Service 51e54d
extern "C" {
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
Packit Service 51e54d
/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
Packit Service 51e54d
   alloca(N); otherwise it returns NULL.  It either returns N bytes of
Packit Service 51e54d
   memory allocated on the stack, that lasts until the function returns,
Packit Service 51e54d
   or NULL.
Packit Service 51e54d
   Use of safe_alloca should be avoided:
Packit Service 51e54d
     - inside arguments of function calls - undefined behaviour,
Packit Service 51e54d
     - in inline functions - the allocation may actually last until the
Packit Service 51e54d
       calling function returns.
Packit Service 51e54d
*/
Packit Service 51e54d
#if HAVE_ALLOCA
Packit Service 51e54d
/* The OS usually guarantees only one guard page at the bottom of the stack,
Packit Service 51e54d
   and a page size can be as small as 4096 bytes.  So we cannot safely
Packit Service 51e54d
   allocate anything larger than 4096 bytes.  Also care for the possibility
Packit Service 51e54d
   of a few compiler-allocated temporary stack slots.
Packit Service 51e54d
   This must be a macro, not a function.  */
Packit Service 51e54d
# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
Packit Service 51e54d
#else
Packit Service 51e54d
# define safe_alloca(N) ((void) (N), NULL)
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
/* malloca(N) is a safe variant of alloca(N).  It allocates N bytes of
Packit Service 51e54d
   memory allocated on the stack, that must be freed using freea() before
Packit Service 51e54d
   the function returns.  Upon failure, it returns NULL.  */
Packit Service 51e54d
#if HAVE_ALLOCA
Packit Service 51e54d
# define malloca(N) \
Packit Service 51e54d
  ((N) < 4032 - sa_increment                                        \
Packit Service 51e54d
   ? (void *) ((char *) alloca ((N) + sa_increment) + sa_increment) \
Packit Service 51e54d
   : mmalloca (N))
Packit Service 51e54d
#else
Packit Service 51e54d
# define malloca(N) \
Packit Service 51e54d
  mmalloca (N)
Packit Service 51e54d
#endif
Packit Service 51e54d
extern void * mmalloca (size_t n);
Packit Service 51e54d
Packit Service 51e54d
/* Free a block of memory allocated through malloca().  */
Packit Service 51e54d
#if HAVE_ALLOCA
Packit Service 51e54d
extern void freea (void *p);
Packit Service 51e54d
#else
Packit Service 51e54d
# define freea free
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
Packit Service 51e54d
   It allocates an array of N objects, each with S bytes of memory,
Packit Service 51e54d
   on the stack.  S must be positive and N must be nonnegative.
Packit Service 51e54d
   The array must be freed using freea() before the function returns.  */
Packit Service 51e54d
#if 1
Packit Service 51e54d
/* Cf. the definition of xalloc_oversized.  */
Packit Service 51e54d
# define nmalloca(n, s) \
Packit Service 51e54d
    ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \
Packit Service 51e54d
     ? NULL \
Packit Service 51e54d
     : malloca ((n) * (s)))
Packit Service 51e54d
#else
Packit Service 51e54d
extern void * nmalloca (size_t n, size_t s);
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
Packit Service 51e54d
#ifdef __cplusplus
Packit Service 51e54d
}
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
Packit Service 51e54d
/* ------------------- Auxiliary, non-public definitions ------------------- */
Packit Service 51e54d
Packit Service 51e54d
/* Determine the alignment of a type at compile time.  */
Packit Service 51e54d
#if defined __GNUC__ || defined __IBM__ALIGNOF__
Packit Service 51e54d
# define sa_alignof __alignof__
Packit Service 51e54d
#elif defined __cplusplus
Packit Service 51e54d
  template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
Packit Service 51e54d
# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
Packit Service 51e54d
#elif defined __hpux
Packit Service 51e54d
  /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
Packit Service 51e54d
     values.  */
Packit Service 51e54d
# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
Packit Service 51e54d
#elif defined _AIX
Packit Service 51e54d
  /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
Packit Service 51e54d
     values.  */
Packit Service 51e54d
# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
Packit Service 51e54d
#else
Packit Service 51e54d
# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
Packit Service 51e54d
#endif
Packit Service 51e54d
Packit Service 51e54d
enum
Packit Service 51e54d
{
Packit Service 51e54d
/* The desired alignment of memory allocations is the maximum alignment
Packit Service 51e54d
   among all elementary types.  */
Packit Service 51e54d
  sa_alignment_long = sa_alignof (long),
Packit Service 51e54d
  sa_alignment_double = sa_alignof (double),
Packit Service 51e54d
#if HAVE_LONG_LONG_INT
Packit Service 51e54d
  sa_alignment_longlong = sa_alignof (long long),
Packit Service 51e54d
#endif
Packit Service 51e54d
  sa_alignment_longdouble = sa_alignof (long double),
Packit Service 51e54d
  sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
Packit Service 51e54d
#if HAVE_LONG_LONG_INT
Packit Service 51e54d
                      | (sa_alignment_longlong - 1)
Packit Service 51e54d
#endif
Packit Service 51e54d
                      | (sa_alignment_longdouble - 1)
Packit Service 51e54d
                     ) + 1,
Packit Service 51e54d
/* The increment that guarantees room for a magic word must be >= sizeof (int)
Packit Service 51e54d
   and a multiple of sa_alignment_max.  */
Packit Service 51e54d
  sa_increment = ((sizeof (int) + sa_alignment_max - 1) / sa_alignment_max) * sa_alignment_max
Packit Service 51e54d
};
Packit Service 51e54d
Packit Service 51e54d
#endif /* _MALLOCA_H */