diff options
Diffstat (limited to 'gl/m4/malloc.m4')
-rw-r--r-- | gl/m4/malloc.m4 | 170 |
1 files changed, 123 insertions, 47 deletions
diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4 index 4b24a0b1..972e808a 100644 --- a/gl/m4/malloc.m4 +++ b/gl/m4/malloc.m4 | |||
@@ -1,98 +1,174 @@ | |||
1 | # malloc.m4 serial 14 | 1 | # malloc.m4 serial 27 |
2 | dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. | 2 | dnl Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc. |
3 | dnl This file is free software; the Free Software Foundation | 3 | dnl This file is free software; the Free Software Foundation |
4 | dnl gives unlimited permission to copy and/or distribute it, | 4 | dnl gives unlimited permission to copy and/or distribute it, |
5 | dnl with or without modifications, as long as this notice is preserved. | 5 | dnl with or without modifications, as long as this notice is preserved. |
6 | 6 | ||
7 | m4_version_prereq([2.70], [] ,[ | 7 | # This is adapted with modifications from upstream Autoconf here: |
8 | 8 | # https://git.savannah.gnu.org/cgit/autoconf.git/tree/lib/autoconf/functions.m4?id=v2.70#n949 | |
9 | # This is taken from the following Autoconf patch: | ||
10 | # http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=7fbb553727ed7e0e689a17594b58559ecf3ea6e9 | ||
11 | AC_DEFUN([_AC_FUNC_MALLOC_IF], | 9 | AC_DEFUN([_AC_FUNC_MALLOC_IF], |
12 | [ | 10 | [ |
13 | AC_REQUIRE([AC_HEADER_STDC])dnl | ||
14 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles | 11 | AC_REQUIRE([AC_CANONICAL_HOST])dnl for cross-compiles |
15 | AC_CHECK_HEADERS([stdlib.h]) | 12 | AC_CACHE_CHECK([whether malloc (0) returns nonnull], |
16 | AC_CACHE_CHECK([for GNU libc compatible malloc], | ||
17 | [ac_cv_func_malloc_0_nonnull], | 13 | [ac_cv_func_malloc_0_nonnull], |
18 | [AC_RUN_IFELSE( | 14 | [AC_RUN_IFELSE( |
19 | [AC_LANG_PROGRAM( | 15 | [AC_LANG_PROGRAM( |
20 | [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H | 16 | [[#include <stdlib.h> |
21 | # include <stdlib.h> | ||
22 | #else | ||
23 | char *malloc (); | ||
24 | #endif | ||
25 | ]], | 17 | ]], |
26 | [[return ! malloc (0);]]) | 18 | [[void *p = malloc (0); |
19 | int result = !p; | ||
20 | free (p); | ||
21 | return result;]]) | ||
27 | ], | 22 | ], |
28 | [ac_cv_func_malloc_0_nonnull=yes], | 23 | [ac_cv_func_malloc_0_nonnull=yes], |
29 | [ac_cv_func_malloc_0_nonnull=no], | 24 | [ac_cv_func_malloc_0_nonnull=no], |
30 | [case "$host_os" in | 25 | [case "$host_os" in |
31 | # Guess yes on platforms where we know the result. | 26 | # Guess yes on platforms where we know the result. |
32 | *-gnu* | freebsd* | netbsd* | openbsd* \ | 27 | *-gnu* | freebsd* | netbsd* | openbsd* | bitrig* \ |
33 | | hpux* | solaris* | cygwin* | mingw*) | 28 | | gnu* | *-musl* | midnightbsd* \ |
34 | ac_cv_func_malloc_0_nonnull=yes ;; | 29 | | hpux* | solaris* | cygwin* | mingw* | msys* ) |
35 | # If we don't know, assume the worst. | 30 | ac_cv_func_malloc_0_nonnull="guessing yes" ;; |
36 | *) ac_cv_func_malloc_0_nonnull=no ;; | 31 | # If we don't know, obey --enable-cross-guesses. |
32 | *) ac_cv_func_malloc_0_nonnull="$gl_cross_guess_normal" ;; | ||
37 | esac | 33 | esac |
38 | ]) | 34 | ]) |
39 | ]) | 35 | ]) |
40 | AS_IF([test $ac_cv_func_malloc_0_nonnull = yes], [$1], [$2]) | 36 | AS_CASE([$ac_cv_func_malloc_0_nonnull], [*yes], [$1], [$2]) |
41 | ])# _AC_FUNC_MALLOC_IF | 37 | ])# _AC_FUNC_MALLOC_IF |
42 | 38 | ||
43 | ]) | ||
44 | |||
45 | # gl_FUNC_MALLOC_GNU | 39 | # gl_FUNC_MALLOC_GNU |
46 | # ------------------ | 40 | # ------------------ |
47 | # Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if | 41 | # Replace malloc if it is not compatible with GNU libc. |
48 | # it is not. | ||
49 | AC_DEFUN([gl_FUNC_MALLOC_GNU], | 42 | AC_DEFUN([gl_FUNC_MALLOC_GNU], |
50 | [ | 43 | [ |
51 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 44 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
52 | dnl _AC_FUNC_MALLOC_IF is defined in Autoconf. | 45 | AC_REQUIRE([gl_FUNC_MALLOC_POSIX]) |
53 | _AC_FUNC_MALLOC_IF( | 46 | if test $REPLACE_MALLOC = 0; then |
54 | [AC_DEFINE([HAVE_MALLOC_GNU], [1], | 47 | _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC=1]) |
55 | [Define to 1 if your system has a GNU libc compatible 'malloc' | 48 | fi |
56 | function, and to 0 otherwise.])], | 49 | ]) |
57 | [AC_DEFINE([HAVE_MALLOC_GNU], [0]) | 50 | |
58 | REPLACE_MALLOC=1 | 51 | # gl_FUNC_MALLOC_PTRDIFF |
52 | # ---------------------- | ||
53 | # Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX, | ||
54 | # and replace malloc otherwise. | ||
55 | AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF], | ||
56 | [ | ||
57 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
58 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) | ||
59 | test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC=1 | ||
60 | ]) | ||
61 | |||
62 | # Test whether malloc, realloc, calloc refuse to create objects | ||
63 | # larger than what can be expressed in ptrdiff_t. | ||
64 | # Set gl_cv_func_malloc_gnu to yes or no accordingly. | ||
65 | AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF], | ||
66 | [ | ||
67 | AC_CACHE_CHECK([whether malloc is ptrdiff_t safe], | ||
68 | [gl_cv_malloc_ptrdiff], | ||
69 | [AC_COMPILE_IFELSE( | ||
70 | [AC_LANG_PROGRAM( | ||
71 | [[#include <stdint.h> | ||
72 | ]], | ||
73 | [[/* 64-bit ptrdiff_t is so wide that no practical platform | ||
74 | can exceed it. */ | ||
75 | #define WIDE_PTRDIFF (PTRDIFF_MAX >> 31 >> 31 != 0) | ||
76 | |||
77 | /* On rare machines where size_t fits in ptrdiff_t there | ||
78 | is no problem. */ | ||
79 | #define NARROW_SIZE (SIZE_MAX <= PTRDIFF_MAX) | ||
80 | |||
81 | /* glibc 2.30 and later malloc refuses to exceed ptrdiff_t | ||
82 | bounds even on 32-bit platforms. We don't know which | ||
83 | non-glibc systems are safe. */ | ||
84 | #define KNOWN_SAFE (2 < __GLIBC__ + (30 <= __GLIBC_MINOR__)) | ||
85 | |||
86 | #if WIDE_PTRDIFF || NARROW_SIZE || KNOWN_SAFE | ||
87 | return 0; | ||
88 | #else | ||
89 | #error "malloc might not be ptrdiff_t safe" | ||
90 | syntax error | ||
91 | #endif | ||
92 | ]])], | ||
93 | [gl_cv_malloc_ptrdiff=yes], | ||
94 | [gl_cv_malloc_ptrdiff=no]) | ||
59 | ]) | 95 | ]) |
60 | ]) | 96 | ]) |
61 | 97 | ||
62 | # gl_FUNC_MALLOC_POSIX | 98 | # gl_FUNC_MALLOC_POSIX |
63 | # -------------------- | 99 | # -------------------- |
64 | # Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it | 100 | # Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it |
65 | # fails), and replace malloc if it is not. | 101 | # fails, and doesn't mess up with ptrdiff_t overflow), and replace |
102 | # malloc if it is not. | ||
66 | AC_DEFUN([gl_FUNC_MALLOC_POSIX], | 103 | AC_DEFUN([gl_FUNC_MALLOC_POSIX], |
67 | [ | 104 | [ |
68 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 105 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
106 | AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF]) | ||
69 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) | 107 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) |
70 | if test $gl_cv_func_malloc_posix = yes; then | 108 | if test "$gl_cv_func_malloc_posix" = yes; then |
71 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], | 109 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], |
72 | [Define if the 'malloc' function is POSIX compliant.]) | 110 | [Define if malloc, realloc, and calloc set errno on allocation failure.]) |
73 | else | 111 | else |
74 | REPLACE_MALLOC=1 | 112 | REPLACE_MALLOC=1 |
75 | fi | 113 | fi |
76 | ]) | 114 | ]) |
77 | 115 | ||
78 | # Test whether malloc, realloc, calloc are POSIX compliant, | 116 | # Test whether malloc, realloc, calloc set errno to ENOMEM on failure. |
79 | # Set gl_cv_func_malloc_posix to yes or no accordingly. | 117 | # Set gl_cv_func_malloc_posix to yes or no accordingly. |
80 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], | 118 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], |
81 | [ | 119 | [ |
82 | AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], | 120 | AC_REQUIRE([AC_CANONICAL_HOST]) |
121 | AC_CACHE_CHECK([whether malloc, realloc, calloc set errno on failure], | ||
83 | [gl_cv_func_malloc_posix], | 122 | [gl_cv_func_malloc_posix], |
84 | [ | 123 | [ |
85 | dnl It is too dangerous to try to allocate a large amount of memory: | 124 | dnl It is too dangerous to try to allocate a large amount of memory: |
86 | dnl some systems go to their knees when you do that. So assume that | 125 | dnl some systems go to their knees when you do that. So assume that |
87 | dnl all Unix implementations of the function are POSIX compliant. | 126 | dnl all Unix implementations of the function set errno on failure, |
88 | AC_COMPILE_IFELSE( | 127 | dnl except on those platforms where we have seen 'test-malloc-gnu', |
89 | [AC_LANG_PROGRAM( | 128 | dnl 'test-realloc-gnu', 'test-calloc-gnu' fail. |
90 | [[]], | 129 | case "$host_os" in |
91 | [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | 130 | mingw*) |
92 | choke me | 131 | gl_cv_func_malloc_posix=no ;; |
93 | #endif | 132 | irix* | solaris*) |
94 | ]])], | 133 | dnl On IRIX 6.5, the three functions return NULL with errno unset |
95 | [gl_cv_func_malloc_posix=yes], | 134 | dnl when the argument is larger than PTRDIFF_MAX. |
96 | [gl_cv_func_malloc_posix=no]) | 135 | dnl On Solaris 11.3, the three functions return NULL with errno set |
136 | dnl to EAGAIN, not ENOMEM, when the argument is larger than | ||
137 | dnl PTRDIFF_MAX. | ||
138 | dnl Here is a test program: | ||
139 | m4_divert_push([KILL]) | ||
140 | #include <errno.h> | ||
141 | #include <stdio.h> | ||
142 | #include <stdlib.h> | ||
143 | #define ptrdiff_t long | ||
144 | #ifndef PTRDIFF_MAX | ||
145 | # define PTRDIFF_MAX ((ptrdiff_t) ((1UL << (8 * sizeof (ptrdiff_t) - 1)) - 1)) | ||
146 | #endif | ||
147 | |||
148 | int main () | ||
149 | { | ||
150 | void *p; | ||
151 | |||
152 | fprintf (stderr, "PTRDIFF_MAX = %lu\n", (unsigned long) PTRDIFF_MAX); | ||
153 | |||
154 | errno = 0; | ||
155 | p = malloc ((unsigned long) PTRDIFF_MAX + 1); | ||
156 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
157 | |||
158 | errno = 0; | ||
159 | p = calloc (PTRDIFF_MAX / 2 + 1, 2); | ||
160 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
161 | |||
162 | errno = 0; | ||
163 | p = realloc (NULL, (unsigned long) PTRDIFF_MAX + 1); | ||
164 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | m4_divert_pop([KILL]) | ||
169 | gl_cv_func_malloc_posix=no ;; | ||
170 | *) | ||
171 | gl_cv_func_malloc_posix=yes ;; | ||
172 | esac | ||
97 | ]) | 173 | ]) |
98 | ]) | 174 | ]) |