xref: /dflybsd-src/contrib/grep/lib/malloca.h (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
195b7b453SJohn Marino /* Safe automatic memory allocation.
2*09d4459fSDaniel Fojt    Copyright (C) 2003-2007, 2009-2020 Free Software Foundation, Inc.
395b7b453SJohn Marino    Written by Bruno Haible <bruno@clisp.org>, 2003.
495b7b453SJohn Marino 
595b7b453SJohn Marino    This program is free software; you can redistribute it and/or modify
695b7b453SJohn Marino    it under the terms of the GNU General Public License as published by
795b7b453SJohn Marino    the Free Software Foundation; either version 3, or (at your option)
895b7b453SJohn Marino    any later version.
995b7b453SJohn Marino 
1095b7b453SJohn Marino    This program is distributed in the hope that it will be useful,
1195b7b453SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1295b7b453SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1395b7b453SJohn Marino    GNU General Public License for more details.
1495b7b453SJohn Marino 
1595b7b453SJohn Marino    You should have received a copy of the GNU General Public License
16*09d4459fSDaniel Fojt    along with this program; if not, see <https://www.gnu.org/licenses/>.  */
1795b7b453SJohn Marino 
1895b7b453SJohn Marino #ifndef _MALLOCA_H
1995b7b453SJohn Marino #define _MALLOCA_H
2095b7b453SJohn Marino 
2195b7b453SJohn Marino #include <alloca.h>
2295b7b453SJohn Marino #include <stddef.h>
2395b7b453SJohn Marino #include <stdlib.h>
24*09d4459fSDaniel Fojt #include <stdint.h>
25*09d4459fSDaniel Fojt 
26*09d4459fSDaniel Fojt #include "xalloc-oversized.h"
2795b7b453SJohn Marino 
2895b7b453SJohn Marino 
2995b7b453SJohn Marino #ifdef __cplusplus
3095b7b453SJohn Marino extern "C" {
3195b7b453SJohn Marino #endif
3295b7b453SJohn Marino 
3395b7b453SJohn Marino 
3495b7b453SJohn Marino /* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
3595b7b453SJohn Marino    alloca(N); otherwise it returns NULL.  It either returns N bytes of
3695b7b453SJohn Marino    memory allocated on the stack, that lasts until the function returns,
3795b7b453SJohn Marino    or NULL.
3895b7b453SJohn Marino    Use of safe_alloca should be avoided:
3995b7b453SJohn Marino      - inside arguments of function calls - undefined behaviour,
4095b7b453SJohn Marino      - in inline functions - the allocation may actually last until the
4195b7b453SJohn Marino        calling function returns.
4295b7b453SJohn Marino */
4395b7b453SJohn Marino #if HAVE_ALLOCA
4495b7b453SJohn Marino /* The OS usually guarantees only one guard page at the bottom of the stack,
4595b7b453SJohn Marino    and a page size can be as small as 4096 bytes.  So we cannot safely
4695b7b453SJohn Marino    allocate anything larger than 4096 bytes.  Also care for the possibility
4795b7b453SJohn Marino    of a few compiler-allocated temporary stack slots.
48680a9cb8SJohn Marino    This must be a macro, not a function.  */
4995b7b453SJohn Marino # define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
5095b7b453SJohn Marino #else
5195b7b453SJohn Marino # define safe_alloca(N) ((void) (N), NULL)
5295b7b453SJohn Marino #endif
5395b7b453SJohn Marino 
5495b7b453SJohn Marino /* malloca(N) is a safe variant of alloca(N).  It allocates N bytes of
5595b7b453SJohn Marino    memory allocated on the stack, that must be freed using freea() before
5695b7b453SJohn Marino    the function returns.  Upon failure, it returns NULL.  */
5795b7b453SJohn Marino #if HAVE_ALLOCA
5895b7b453SJohn Marino # define malloca(N) \
59*09d4459fSDaniel Fojt   ((N) < 4032 - (2 * sa_alignment_max - 1)                                   \
60*09d4459fSDaniel Fojt    ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
61*09d4459fSDaniel Fojt                 + (2 * sa_alignment_max - 1))                                \
62*09d4459fSDaniel Fojt                & ~(uintptr_t)(2 * sa_alignment_max - 1))                     \
6395b7b453SJohn Marino    : mmalloca (N))
6495b7b453SJohn Marino #else
6595b7b453SJohn Marino # define malloca(N) \
6695b7b453SJohn Marino   mmalloca (N)
6795b7b453SJohn Marino #endif
6895b7b453SJohn Marino extern void * mmalloca (size_t n);
6995b7b453SJohn Marino 
7095b7b453SJohn Marino /* Free a block of memory allocated through malloca().  */
7195b7b453SJohn Marino #if HAVE_ALLOCA
7295b7b453SJohn Marino extern void freea (void *p);
7395b7b453SJohn Marino #else
7495b7b453SJohn Marino # define freea free
7595b7b453SJohn Marino #endif
7695b7b453SJohn Marino 
7795b7b453SJohn Marino /* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
7895b7b453SJohn Marino    It allocates an array of N objects, each with S bytes of memory,
7995b7b453SJohn Marino    on the stack.  S must be positive and N must be nonnegative.
8095b7b453SJohn Marino    The array must be freed using freea() before the function returns.  */
81*09d4459fSDaniel Fojt #define nmalloca(n, s) (xalloc_oversized (n, s) ? NULL : malloca ((n) * (s)))
8295b7b453SJohn Marino 
8395b7b453SJohn Marino 
8495b7b453SJohn Marino #ifdef __cplusplus
8595b7b453SJohn Marino }
8695b7b453SJohn Marino #endif
8795b7b453SJohn Marino 
8895b7b453SJohn Marino 
8995b7b453SJohn Marino /* ------------------- Auxiliary, non-public definitions ------------------- */
9095b7b453SJohn Marino 
9195b7b453SJohn Marino /* Determine the alignment of a type at compile time.  */
92680a9cb8SJohn Marino #if defined __GNUC__ || defined __IBM__ALIGNOF__
9395b7b453SJohn Marino # define sa_alignof __alignof__
9495b7b453SJohn Marino #elif defined __cplusplus
9595b7b453SJohn Marino   template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
9695b7b453SJohn Marino # define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
9795b7b453SJohn Marino #elif defined __hpux
9895b7b453SJohn Marino   /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
9995b7b453SJohn Marino      values.  */
10095b7b453SJohn Marino # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
10195b7b453SJohn Marino #elif defined _AIX
10295b7b453SJohn Marino   /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
10395b7b453SJohn Marino      values.  */
10495b7b453SJohn Marino # define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
10595b7b453SJohn Marino #else
10695b7b453SJohn Marino # define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
10795b7b453SJohn Marino #endif
10895b7b453SJohn Marino 
10995b7b453SJohn Marino enum
11095b7b453SJohn Marino {
11195b7b453SJohn Marino /* The desired alignment of memory allocations is the maximum alignment
11295b7b453SJohn Marino    among all elementary types.  */
11395b7b453SJohn Marino   sa_alignment_long = sa_alignof (long),
11495b7b453SJohn Marino   sa_alignment_double = sa_alignof (double),
11595b7b453SJohn Marino   sa_alignment_longlong = sa_alignof (long long),
11695b7b453SJohn Marino   sa_alignment_longdouble = sa_alignof (long double),
11795b7b453SJohn Marino   sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
11895b7b453SJohn Marino                       | (sa_alignment_longlong - 1)
11995b7b453SJohn Marino                       | (sa_alignment_longdouble - 1)
120*09d4459fSDaniel Fojt                      ) + 1
12195b7b453SJohn Marino };
12295b7b453SJohn Marino 
12395b7b453SJohn Marino #endif /* _MALLOCA_H */
124