From a1da46a05cc65842021511bd6d68560b0240eec7 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 4 Nov 2024 17:50:09 +0100 Subject: [PATCH] aligned_alloc: Fix test failures on macOS, Solaris (regr. 2024-10-30). * m4/aligned_alloc.m4 (gl_FUNC_ALIGNED_ALLOC): Check for the Solaris bug. Let the test program return a bit mask. Update cross-compilation guesses. * lib/aligned_alloc.c: Include . (aligned_alloc): Fail if the alignment is not a power of 2. Work around the Solaris bug. * modules/aligned_alloc (Depends-on): Add malloc-posix. * doc/posix-functions/aligned_alloc.texi: Mention the Solaris bug. --- ChangeLog | 12 ++++++++ doc/posix-functions/aligned_alloc.texi | 21 ++++++++----- lib/aligned_alloc.c | 31 +++++++++++++++---- m4/aligned_alloc.m4 | 41 +++++++++++++++++++------- modules/aligned_alloc | 1 + 5 files changed, 82 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8d0ab77a97..727df3dcb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2024-11-04 Bruno Haible + + aligned_alloc: Fix test failures on macOS, Solaris (regr. 2024-10-30). + * m4/aligned_alloc.m4 (gl_FUNC_ALIGNED_ALLOC): Check for the Solaris + bug. Let the test program return a bit mask. Update cross-compilation + guesses. + * lib/aligned_alloc.c: Include . + (aligned_alloc): Fail if the alignment is not a power of 2. Work around + the Solaris bug. + * modules/aligned_alloc (Depends-on): Add malloc-posix. + * doc/posix-functions/aligned_alloc.texi: Mention the Solaris bug. + 2024-11-04 Bruno Haible tests: Add comments. diff --git a/doc/posix-functions/aligned_alloc.texi b/doc/posix-functions/aligned_alloc.texi index b815bd0532..121c0601c4 100644 --- a/doc/posix-functions/aligned_alloc.texi +++ b/doc/posix-functions/aligned_alloc.texi @@ -18,26 +18,31 @@ This function fails if the alignment argument is smaller than @code{sizeof (void *)} on some platforms: macOS 14, AIX 7.3.1. +@item +This function returns a null pointer if the requested size is +not a multiple of the alignment: +Solaris 11.4. + @item This function returns a null pointer if the size argument is zero: -AIX 7.3. -@end itemize +macOS 15, AIX 7.3, Solaris 11.4. -Portability problems not fixed by Gnulib: -@itemize @item On some platforms, @code{aligned_alloc} crashes if the requested size is not a multiple of the alignment: AddressSanitizer (gcc 11.2 or clang 13). +@end itemize + +Portability problems not fixed by Gnulib: +@itemize +@item +This function is missing on many older platforms: +glibc 2.15, macOS 10.14, FreeBSD 6.4, NetBSD 7.1, OpenBSD 6.0, Minix 3.1.8, AIX 7.1, HP-UX 11.31, Solaris 11.3, Cygwin 1.7.x, mingw, MSVC 14, Android 8.1. @item If the alignment and size are absurdly large, this function crashes: @c https://sourceware.org/bugzilla/show_bug.cgi?id=32301 glibc 2.40. - -@item -This function is missing on many older platforms: -glibc 2.15, macOS 10.14, FreeBSD 6.4, NetBSD 7.1, OpenBSD 6.0, Minix 3.1.8, AIX 7.1, HP-UX 11.31, Solaris 11.3, Cygwin 1.7.x, mingw, MSVC 14, Android 8.1. @end itemize Gnulib has partial substitutes for @code{aligned_alloc} diff --git a/lib/aligned_alloc.c b/lib/aligned_alloc.c index 947ec1257c..a9f43ec0c1 100644 --- a/lib/aligned_alloc.c +++ b/lib/aligned_alloc.c @@ -19,14 +19,35 @@ /* Specification. */ #include +#include + void * aligned_alloc (size_t alignment, size_t size) #undef aligned_alloc { - if (size == 0) - size = 1; - if (alignment >= sizeof (void *)) - return aligned_alloc (alignment, size); + if (alignment != 0 && (alignment & (alignment - 1)) == 0) + { + /* alignment is a power of 2. */ + if (size == 0) + size = 1; + if (alignment >= sizeof (void *)) + { + /* Make size a multiple of alignment. */ + size = (size + (alignment - 1)) & -alignment; + if (size > 0) + return aligned_alloc (alignment, size); + else + { + errno = ENOMEM; + return NULL; + } + } + else + return malloc (size); + } else - return malloc (size); + { + errno = EINVAL; + return NULL; + } } diff --git a/m4/aligned_alloc.m4 b/m4/aligned_alloc.m4 index 2d4a377e19..0d3e35135e 100644 --- a/m4/aligned_alloc.m4 +++ b/m4/aligned_alloc.m4 @@ -1,5 +1,5 @@ # aligned_alloc.m4 -# serial 8 +# serial 9 dnl Copyright (C) 2020-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -18,7 +18,10 @@ AC_DEFUN([gl_FUNC_ALIGNED_ALLOC], if test $ac_cv_func_aligned_alloc = yes; then dnl On macOS 11.1 and AIX 7.3.1, aligned_alloc returns NULL when the dnl alignment argument is smaller than sizeof (void *). - dnl On AIX 7.3, aligned_alloc with a zero size returns NULL. + dnl On Solaris 11.4, aligned_alloc returns NULL if the size is not a + dnl multiple of the alignment. + dnl On macOS 15, AIX 7.3, Solaris 11.4, aligned_alloc with a zero size + dnl returns NULL. AC_CACHE_CHECK([whether aligned_alloc works for small alignments and sizes], [gl_cv_func_aligned_alloc_works], [AC_RUN_IFELSE( @@ -28,20 +31,36 @@ AC_DEFUN([gl_FUNC_ALIGNED_ALLOC], from optimizing the aligned_alloc call away. */ void *(*volatile paligned_alloc) (size_t, size_t) = aligned_alloc;]], - [[void *p = paligned_alloc (2, 18); - void *q = paligned_alloc (sizeof (void *), 0); - return p == NULL || q == NULL; + [[int result = 0; + { + void *p = paligned_alloc (2, 18); + if (p == NULL) + result |= 1; + } + { + void *p = paligned_alloc (sizeof (void *), sizeof (void *) + 1); + if (p == NULL) + result |= 2; + } + { + void *p = paligned_alloc (sizeof (void *), 0); + if (p == NULL) + result |= 4; + } + return result; ]]) ], [gl_cv_func_aligned_alloc_works=yes], [gl_cv_func_aligned_alloc_works=no], [case "$host_os" in - # Guess no on AIX. - aix*) gl_cv_func_aligned_alloc_works="guessing no" ;; - # Guess no on macOS. - darwin*) gl_cv_func_aligned_alloc_works="guessing no" ;; - # If we don't know, obey --enable-cross-guesses. - *) gl_cv_func_aligned_alloc_works="$gl_cross_guess_normal" ;; + # Guess no on macOS. + darwin*) gl_cv_func_aligned_alloc_works="guessing no" ;; + # Guess no on AIX. + aix*) gl_cv_func_aligned_alloc_works="guessing no" ;; + # Guess no on Solaris. + solaris*) gl_cv_func_aligned_alloc_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_aligned_alloc_works="$gl_cross_guess_normal" ;; esac ]) ]) diff --git a/modules/aligned_alloc b/modules/aligned_alloc index e04115ec9e..ab7f3ffba0 100644 --- a/modules/aligned_alloc +++ b/modules/aligned_alloc @@ -8,6 +8,7 @@ m4/aligned_alloc.m4 Depends-on: extensions stdlib +malloc-posix [test $REPLACE_ALIGNED_ALLOC = 1] configure.ac: gl_FUNC_ALIGNED_ALLOC -- 2.39.5