167754Smsmith/* Safe automatic memory allocation.
267754Smsmith   Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc.
377424Smsmith   Written by Bruno Haible <bruno@clisp.org>, 2003.
467754Smsmith
567754Smsmith   This file is free software: you can redistribute it and/or modify
667754Smsmith   it under the terms of the GNU Lesser General Public License as
7217365Sjkim   published by the Free Software Foundation; either version 2.1 of the
8245582Sjkim   License, or (at your option) any later version.
970243Smsmith
1067754Smsmith   This file is distributed in the hope that it will be useful,
11217365Sjkim   but WITHOUT ANY WARRANTY; without even the implied warranty of
12217365Sjkim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13217365Sjkim   GNU Lesser General Public License for more details.
14217365Sjkim
15217365Sjkim   You should have received a copy of the GNU Lesser General Public License
16217365Sjkim   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17217365Sjkim
18217365Sjkim#ifndef _MALLOCA_H
19217365Sjkim#define _MALLOCA_H
20217365Sjkim
21217365Sjkim#include <alloca.h>
22217365Sjkim#include <stddef.h>
23217365Sjkim#include <stdlib.h>
24217365Sjkim#include <stdint.h>
2567754Smsmith
26217365Sjkim#include "xalloc-oversized.h"
27217365Sjkim
28217365Sjkim
2967754Smsmith#ifdef __cplusplus
30217365Sjkimextern "C" {
31217365Sjkim#endif
32217365Sjkim
33217365Sjkim
34217365Sjkim/* safe_alloca(N) is equivalent to alloca(N) when it is safe to call
35217365Sjkim   alloca(N); otherwise it returns NULL.  It either returns N bytes of
36217365Sjkim   memory allocated on the stack, that lasts until the function returns,
37217365Sjkim   or NULL.
38217365Sjkim   Use of safe_alloca should be avoided:
39217365Sjkim     - inside arguments of function calls - undefined behaviour,
40217365Sjkim     - in inline functions - the allocation may actually last until the
41217365Sjkim       calling function returns.
42217365Sjkim*/
4367754Smsmith#if HAVE_ALLOCA
4477424Smsmith/* The OS usually guarantees only one guard page at the bottom of the stack,
4577424Smsmith   and a page size can be as small as 4096 bytes.  So we cannot safely
4667754Smsmith   allocate anything larger than 4096 bytes.  Also care for the possibility
4767754Smsmith   of a few compiler-allocated temporary stack slots.
48167802Sjkim   This must be a macro, not a function.  */
49228110Sjkim# define safe_alloca(N) ((N) < 4032 ? alloca (N) : NULL)
50167802Sjkim#else
51167802Sjkim# define safe_alloca(N) ((void) (N), NULL)
52167802Sjkim#endif
53167802Sjkim
54167802Sjkim/* Free a block of memory allocated through malloca().  */
55167802Sjkim#if HAVE_ALLOCA
56167802Sjkimextern void freea (void *p);
57167802Sjkim#else
58167802Sjkim# define freea free
59167802Sjkim#endif
60167802Sjkim
61167802Sjkim/* malloca(N) is a safe variant of alloca(N).  It allocates N bytes of
62167802Sjkim   memory allocated on the stack, that must be freed using freea() before
63167802Sjkim   the function returns.  Upon failure, it returns NULL.  */
64167802Sjkim#if HAVE_ALLOCA
65167802Sjkim# define malloca(N) \
66167802Sjkim  ((N) < 4032 - (2 * sa_alignment_max - 1)                                   \
67167802Sjkim   ? (void *) (((uintptr_t) (char *) alloca ((N) + 2 * sa_alignment_max - 1) \
68167802Sjkim                + (2 * sa_alignment_max - 1))                                \
69167802Sjkim               & ~(uintptr_t)(2 * sa_alignment_max - 1))                     \
70167802Sjkim   : mmalloca (N))
71167802Sjkim#else
72167802Sjkim# define malloca(N) \
73228110Sjkim  mmalloca (N)
74228110Sjkim#endif
75228110Sjkimextern void *mmalloca (size_t n)
76228110Sjkim  _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (freea, 1)
77228110Sjkim  _GL_ATTRIBUTE_ALLOC_SIZE ((1));
78228110Sjkim
79228110Sjkim/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S).
80228110Sjkim   It allocates an array of N objects, each with S bytes of memory,
81228110Sjkim   on the stack.  N and S should be nonnegative and free of side effects.
82228110Sjkim   The array must be freed using freea() before the function returns.  */
83228110Sjkim#define nmalloca(n, s) \
84228110Sjkim  (xalloc_oversized (n, s) ? NULL : malloca ((n) * (size_t) (s)))
85228110Sjkim
86228110Sjkim
87228110Sjkim#ifdef __cplusplus
88228110Sjkim}
89167802Sjkim#endif
90167802Sjkim
91250838Sjkim
92250838Sjkim/* ------------------- Auxiliary, non-public definitions ------------------- */
93250838Sjkim
94250838Sjkim/* Determine the alignment of a type at compile time.  */
95250838Sjkim#if defined __GNUC__ || defined __clang__ || defined __IBM__ALIGNOF__
96250838Sjkim# define sa_alignof __alignof__
97250838Sjkim#elif defined __cplusplus
98250838Sjkim  template <class type> struct sa_alignof_helper { char __slot1; type __slot2; };
99250838Sjkim# define sa_alignof(type) offsetof (sa_alignof_helper<type>, __slot2)
100250838Sjkim#elif defined __hpux
101250838Sjkim  /* Work around a HP-UX 10.20 cc bug with enums constants defined as offsetof
102250838Sjkim     values.  */
103250838Sjkim# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
104250838Sjkim#elif defined _AIX
105250838Sjkim  /* Work around an AIX 3.2.5 xlc bug with enums constants defined as offsetof
106250838Sjkim     values.  */
107250838Sjkim# define sa_alignof(type) (sizeof (type) <= 4 ? 4 : 8)
108250838Sjkim#else
109250838Sjkim# define sa_alignof(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
110250838Sjkim#endif
111250838Sjkim
112250838Sjkimenum
113250838Sjkim{
114250838Sjkim/* The desired alignment of memory allocations is the maximum alignment
115250838Sjkim   among all elementary types.  */
116250838Sjkim  sa_alignment_long = sa_alignof (long),
117250838Sjkim  sa_alignment_double = sa_alignof (double),
118250838Sjkim  sa_alignment_longlong = sa_alignof (long long),
119250838Sjkim  sa_alignment_longdouble = sa_alignof (long double),
120250838Sjkim  sa_alignment_max = ((sa_alignment_long - 1) | (sa_alignment_double - 1)
121250838Sjkim                      | (sa_alignment_longlong - 1)
122250838Sjkim                      | (sa_alignment_longdouble - 1)
123250838Sjkim                     ) + 1
124250838Sjkim};
125250838Sjkim
126250838Sjkim#endif /* _MALLOCA_H */
127250838Sjkim