diff options
Diffstat (limited to 'gl/m4/malloc.m4')
| -rw-r--r-- | gl/m4/malloc.m4 | 173 |
1 files changed, 125 insertions, 48 deletions
diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4 index 4b24a0b1..55402924 100644 --- a/gl/m4/malloc.m4 +++ b/gl/m4/malloc.m4 | |||
| @@ -1,98 +1,175 @@ | |||
| 1 | # malloc.m4 serial 14 | 1 | # malloc.m4 serial 28 |
| 2 | dnl Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc. | 2 | dnl Copyright (C) 2007, 2009-2023 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 | REPLACE_MALLOC_FOR_MALLOC_GNU="$REPLACE_MALLOC_FOR_MALLOC_POSIX" |
| 54 | [AC_DEFINE([HAVE_MALLOC_GNU], [1], | 47 | if test $REPLACE_MALLOC_FOR_MALLOC_GNU = 0; then |
| 55 | [Define to 1 if your system has a GNU libc compatible 'malloc' | 48 | _AC_FUNC_MALLOC_IF([], [REPLACE_MALLOC_FOR_MALLOC_GNU=1]) |
| 56 | function, and to 0 otherwise.])], | 49 | fi |
| 57 | [AC_DEFINE([HAVE_MALLOC_GNU], [0]) | 50 | ]) |
| 58 | REPLACE_MALLOC=1 | 51 | |
| 52 | # gl_FUNC_MALLOC_PTRDIFF | ||
| 53 | # ---------------------- | ||
| 54 | # Test whether malloc (N) reliably fails when N exceeds PTRDIFF_MAX, | ||
| 55 | # and replace malloc otherwise. | ||
| 56 | AC_DEFUN([gl_FUNC_MALLOC_PTRDIFF], | ||
| 57 | [ | ||
| 58 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | ||
| 59 | AC_REQUIRE([gl_CHECK_MALLOC_PTRDIFF]) | ||
| 60 | test "$gl_cv_malloc_ptrdiff" = yes || REPLACE_MALLOC_FOR_MALLOC_POSIX=1 | ||
| 61 | ]) | ||
| 62 | |||
| 63 | # Test whether malloc, realloc, calloc refuse to create objects | ||
| 64 | # larger than what can be expressed in ptrdiff_t. | ||
| 65 | # Set gl_cv_func_malloc_gnu to yes or no accordingly. | ||
| 66 | AC_DEFUN([gl_CHECK_MALLOC_PTRDIFF], | ||
| 67 | [ | ||
| 68 | AC_CACHE_CHECK([whether malloc is ptrdiff_t safe], | ||
| 69 | [gl_cv_malloc_ptrdiff], | ||
| 70 | [AC_COMPILE_IFELSE( | ||
| 71 | [AC_LANG_PROGRAM( | ||
| 72 | [[#include <stdint.h> | ||
| 73 | ]], | ||
| 74 | [[/* 64-bit ptrdiff_t is so wide that no practical platform | ||
| 75 | can exceed it. */ | ||
| 76 | #define WIDE_PTRDIFF (PTRDIFF_MAX >> 31 >> 31 != 0) | ||
| 77 | |||
| 78 | /* On rare machines where size_t fits in ptrdiff_t there | ||
| 79 | is no problem. */ | ||
| 80 | #define NARROW_SIZE (SIZE_MAX <= PTRDIFF_MAX) | ||
| 81 | |||
| 82 | /* glibc 2.30 and later malloc refuses to exceed ptrdiff_t | ||
| 83 | bounds even on 32-bit platforms. We don't know which | ||
| 84 | non-glibc systems are safe. */ | ||
| 85 | #define KNOWN_SAFE (2 < __GLIBC__ + (30 <= __GLIBC_MINOR__)) | ||
| 86 | |||
| 87 | #if WIDE_PTRDIFF || NARROW_SIZE || KNOWN_SAFE | ||
| 88 | return 0; | ||
| 89 | #else | ||
| 90 | #error "malloc might not be ptrdiff_t safe" | ||
| 91 | syntax error | ||
| 92 | #endif | ||
| 93 | ]])], | ||
| 94 | [gl_cv_malloc_ptrdiff=yes], | ||
| 95 | [gl_cv_malloc_ptrdiff=no]) | ||
| 59 | ]) | 96 | ]) |
| 60 | ]) | 97 | ]) |
| 61 | 98 | ||
| 62 | # gl_FUNC_MALLOC_POSIX | 99 | # gl_FUNC_MALLOC_POSIX |
| 63 | # -------------------- | 100 | # -------------------- |
| 64 | # Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it | 101 | # Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it |
| 65 | # fails), and replace malloc if it is not. | 102 | # fails, and doesn't mess up with ptrdiff_t overflow), and replace |
| 103 | # malloc if it is not. | ||
| 66 | AC_DEFUN([gl_FUNC_MALLOC_POSIX], | 104 | AC_DEFUN([gl_FUNC_MALLOC_POSIX], |
| 67 | [ | 105 | [ |
| 68 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) | 106 | AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) |
| 107 | AC_REQUIRE([gl_FUNC_MALLOC_PTRDIFF]) | ||
| 69 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) | 108 | AC_REQUIRE([gl_CHECK_MALLOC_POSIX]) |
| 70 | if test $gl_cv_func_malloc_posix = yes; then | 109 | if test "$gl_cv_func_malloc_posix" = yes; then |
| 71 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], | 110 | AC_DEFINE([HAVE_MALLOC_POSIX], [1], |
| 72 | [Define if the 'malloc' function is POSIX compliant.]) | 111 | [Define if malloc, realloc, and calloc set errno on allocation failure.]) |
| 73 | else | 112 | else |
| 74 | REPLACE_MALLOC=1 | 113 | REPLACE_MALLOC_FOR_MALLOC_POSIX=1 |
| 75 | fi | 114 | fi |
| 76 | ]) | 115 | ]) |
| 77 | 116 | ||
| 78 | # Test whether malloc, realloc, calloc are POSIX compliant, | 117 | # Test whether malloc, realloc, calloc set errno to ENOMEM on failure. |
| 79 | # Set gl_cv_func_malloc_posix to yes or no accordingly. | 118 | # Set gl_cv_func_malloc_posix to yes or no accordingly. |
| 80 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], | 119 | AC_DEFUN([gl_CHECK_MALLOC_POSIX], |
| 81 | [ | 120 | [ |
| 82 | AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant], | 121 | AC_REQUIRE([AC_CANONICAL_HOST]) |
| 122 | AC_CACHE_CHECK([whether malloc, realloc, calloc set errno on failure], | ||
| 83 | [gl_cv_func_malloc_posix], | 123 | [gl_cv_func_malloc_posix], |
| 84 | [ | 124 | [ |
| 85 | dnl It is too dangerous to try to allocate a large amount of memory: | 125 | 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 | 126 | 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. | 127 | dnl all Unix implementations of the function set errno on failure, |
| 88 | AC_COMPILE_IFELSE( | 128 | dnl except on those platforms where we have seen 'test-malloc-gnu', |
| 89 | [AC_LANG_PROGRAM( | 129 | dnl 'test-realloc-gnu', 'test-calloc-gnu' fail. |
| 90 | [[]], | 130 | case "$host_os" in |
| 91 | [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | 131 | mingw*) |
| 92 | choke me | 132 | gl_cv_func_malloc_posix=no ;; |
| 93 | #endif | 133 | irix* | solaris*) |
| 94 | ]])], | 134 | dnl On IRIX 6.5, the three functions return NULL with errno unset |
| 95 | [gl_cv_func_malloc_posix=yes], | 135 | dnl when the argument is larger than PTRDIFF_MAX. |
| 96 | [gl_cv_func_malloc_posix=no]) | 136 | dnl On Solaris 11.3, the three functions return NULL with errno set |
| 137 | dnl to EAGAIN, not ENOMEM, when the argument is larger than | ||
| 138 | dnl PTRDIFF_MAX. | ||
| 139 | dnl Here is a test program: | ||
| 140 | m4_divert_push([KILL]) | ||
| 141 | #include <errno.h> | ||
| 142 | #include <stdio.h> | ||
| 143 | #include <stdlib.h> | ||
| 144 | #define ptrdiff_t long | ||
| 145 | #ifndef PTRDIFF_MAX | ||
| 146 | # define PTRDIFF_MAX ((ptrdiff_t) ((1UL << (8 * sizeof (ptrdiff_t) - 1)) - 1)) | ||
| 147 | #endif | ||
| 148 | |||
| 149 | int main () | ||
| 150 | { | ||
| 151 | void *p; | ||
| 152 | |||
| 153 | fprintf (stderr, "PTRDIFF_MAX = %lu\n", (unsigned long) PTRDIFF_MAX); | ||
| 154 | |||
| 155 | errno = 0; | ||
| 156 | p = malloc ((unsigned long) PTRDIFF_MAX + 1); | ||
| 157 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
| 158 | |||
| 159 | errno = 0; | ||
| 160 | p = calloc (PTRDIFF_MAX / 2 + 1, 2); | ||
| 161 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
| 162 | |||
| 163 | errno = 0; | ||
| 164 | p = realloc (NULL, (unsigned long) PTRDIFF_MAX + 1); | ||
| 165 | fprintf (stderr, "p=%p errno=%d\n", p, errno); | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | m4_divert_pop([KILL]) | ||
| 170 | gl_cv_func_malloc_posix=no ;; | ||
| 171 | *) | ||
| 172 | gl_cv_func_malloc_posix=yes ;; | ||
| 173 | esac | ||
| 97 | ]) | 174 | ]) |
| 98 | ]) | 175 | ]) |
