Annotation of embedaddon/libiconv/srclib/malloca.h, revision 1.1.1.3

1.1       misho       1: /* Safe automatic memory allocation.
1.1.1.3 ! misho       2:    Copyright (C) 2003-2007, 2009-2019 Free Software Foundation, Inc.
1.1       misho       3:    Written by Bruno Haible <bruno@clisp.org>, 2003.
                      4: 
                      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, or (at your option)
                      8:    any later version.
                      9: 
                     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.
                     14: 
                     15:    You should have received a copy of the GNU General Public License
1.1.1.3 ! misho      16:    along with this program; if not, see <https://www.gnu.org/licenses/>.  */
1.1       misho      17: 
                     18: #ifndef _MALLOCA_H
                     19: #define _MALLOCA_H
                     20: 
                     21: #include <alloca.h>
                     22: #include <stddef.h>
                     23: #include <stdlib.h>
1.1.1.3 ! misho      24: #include <stdint.h>
        !            25: 
        !            26: #include "xalloc-oversized.h"
1.1       misho      27: 
                     28: 
                     29: #ifdef __cplusplus
                     30: extern "C" {
                     31: #endif
                     32: 
                     33: 
                     34: /* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
                     35:    alloca(N); otherwise it returns NULL.  It either returns N bytes of
                     36:    memory allocated on the stack, that lasts until the function returns,
                     37:    or NULL.
                     38:    Use of safe_alloca should be avoided:
                     39:      - inside arguments of function calls - undefined behaviour,
                     40:      - in inline functions - the allocation may actually last until the
                     41:        calling function returns.
                     42: */
                     43: #if HAVE_ALLOCA
                     44: /* The OS usually guarantees only one guard page at the bottom of the stack,
                     45:    and a page size can be as small as 4096 bytes.  So we cannot safely
                     46:    allocate anything larger than 4096 bytes.  Also care for the possibility
                     47:    of a few compiler-allocated temporary stack slots.
1.1.1.3 ! misho      48:    This must be a macro, not a function.  */
1.1       misho      49: # define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
                     50: #else
                     51: # define safe_alloca(N) ((void) (N), NULL)
                     52: #endif
                     53: 
                     54: /* malloca(N) is a safe variant of alloca(N).  It allocates N bytes of
                     55:    memory allocated on the stack, that must be freed using freea() before
                     56:    the function returns.  Upon failure, it returns NULL.  */
                     57: #if HAVE_ALLOCA
                     58: # define malloca(N) \
1.1.1.3 ! misho      59:   ((N) < 4032 - (2 * sa_alignment_max - 1)                                   \
        !            60:    ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
        !            61:                 + (2 * sa_alignment_max - 1))                                \
        !            62:                & ~(uintptr_t)(2 * sa_alignment_max - 1))                     \
1.1       misho      63:    : mmalloca (N))
                     64: #else
                     65: # define malloca(N) \
                     66:   mmalloca (N)
                     67: #endif
                     68: extern void * mmalloca (size_t n);
                     69: 
                     70: /* Free a block of memory allocated through malloca().  */
                     71: #if HAVE_ALLOCA
                     72: extern void freea (void *p);
                     73: #else
                     74: # define freea free
                     75: #endif
                     76: 
                     77: /* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
                     78:    It allocates an array of N objects, each with S bytes of memory,
                     79:    on the stack.  S must be positive and N must be nonnegative.
                     80:    The array must be freed using freea() before the function returns.  */
1.1.1.3 ! misho      81: #define nmalloca(n, s) (xalloc_oversized (n, s) ? NULL : malloca ((n) * (s)))
1.1       misho      82: 
                     83: 
                     84: #ifdef __cplusplus
                     85: }
                     86: #endif
                     87: 
                     88: 
                     89: /* ------------------- Auxiliary, non-public definitions ------------------- */
                     90: 
                     91: /* Determine the alignment of a type at compile time.  */
1.1.1.3 ! misho      92: #if defined __GNUC__ || defined __IBM__ALIGNOF__
1.1       misho      93: # define sa_alignof __alignof__
                     94: #elif defined __cplusplus
                     95:   template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
                     96: # define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
                     97: #elif defined __hpux
                     98:   /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
                     99:      values.  */
                    100: # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
                    101: #elif defined _AIX
                    102:   /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
                    103:      values.  */
                    104: # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
                    105: #else
                    106: # define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
                    107: #endif
                    108: 
                    109: enum
                    110: {
                    111: /* The desired alignment of memory allocations is the maximum alignment
                    112:    among all elementary types.  */
                    113:   sa_alignment_long = sa_alignof (long),
                    114:   sa_alignment_double = sa_alignof (double),
                    115: #if HAVE_LONG_LONG_INT
                    116:   sa_alignment_longlong = sa_alignof (long long),
                    117: #endif
                    118:   sa_alignment_longdouble = sa_alignof (long double),
                    119:   sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
                    120: #if HAVE_LONG_LONG_INT
1.1.1.2   misho     121:                       | (sa_alignment_longlong - 1)
1.1       misho     122: #endif
1.1.1.2   misho     123:                       | (sa_alignment_longdouble - 1)
1.1.1.3 ! misho     124:                      ) + 1
1.1       misho     125: };
                    126: 
                    127: #endif /* _MALLOCA_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>