Paul Eggert wrote: > * lib/aligned_alloc.c (aligned_alloc): Treat zero size like GNU. > * m4/aligned_alloc.m4 (gl_FUNC_ALIGNED_ALLOC): > * tests/test-aligned_alloc.c (main): > Test zero size too.
The CI reports that this test fails on macOS 12..15 and Solaris 11.4. On both platforms, aligned_alloc (8, 0) returns NULL. On Solaris 11.4, additionally, aligned_alloc (8, size) with 0 < size < 8 also returns NULL. This patch adds workarounds against both problems. 2024-11-04 Bruno Haible <br...@clisp.org> 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 <errno.h>. (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.
>From 3d5f0e4766b02363dc7e40c79d002ba49bdeee81 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Mon, 4 Nov 2024 13:49:22 +0100 Subject: [PATCH 1/2] tests: Add comments. * tests/test-aligned_alloc.c (main): Clarify that we test a zero size. * tests/test-posix_memalign.c (main): Likewise. --- ChangeLog | 6 ++++++ tests/test-aligned_alloc.c | 5 +++-- tests/test-posix_memalign.c | 5 +++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index c73909152a..8d0ab77a97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-11-04 Bruno Haible <br...@clisp.org> + + tests: Add comments. + * tests/test-aligned_alloc.c (main): Clarify that we test a zero size. + * tests/test-posix_memalign.c (main): Likewise. + 2024-11-04 Bruno Haible <br...@clisp.org> malloc, calloc, realloc tests: Work around clang optimization bug. diff --git a/tests/test-aligned_alloc.c b/tests/test-aligned_alloc.c index e4aba98221..bf953fe85d 100644 --- a/tests/test-aligned_alloc.c +++ b/tests/test-aligned_alloc.c @@ -36,8 +36,9 @@ main (int argc, char *argv[]) #if HAVE_ALIGNED_ALLOC static size_t sizes[] = { - 13, 8, 17, 450, 320, 1, 99, 4, 15, 16, - 2, 76, 37, 127, 2406, 641, 5781, 0 + 13, 8, 17, 450, 320, 1, 99, 4, 15, 16, 2, 76, 37, 127, 2406, 641, 5781, + /* Test also a zero size. */ + 0 }; void *volatile aligned2_blocks[SIZEOF (sizes)]; void *volatile aligned4_blocks[SIZEOF (sizes)]; diff --git a/tests/test-posix_memalign.c b/tests/test-posix_memalign.c index b61ac4e2a0..a9a6fc1593 100644 --- a/tests/test-posix_memalign.c +++ b/tests/test-posix_memalign.c @@ -34,8 +34,9 @@ main (int argc, char *argv[]) #if HAVE_POSIX_MEMALIGN static size_t sizes[] = { - 13, 8, 17, 450, 320, 1, 99, 4, 15, 16, - 2, 76, 37, 127, 2406, 641, 5781, 0 + 13, 8, 17, 450, 320, 1, 99, 4, 15, 16, 2, 76, 37, 127, 2406, 641, 5781, + /* Test also a zero size. */ + 0 }; void *aligned2_blocks[SIZEOF (sizes)]; void *aligned4_blocks[SIZEOF (sizes)]; -- 2.34.1
>From a1da46a05cc65842021511bd6d68560b0240eec7 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Mon, 4 Nov 2024 17:50:09 +0100 Subject: [PATCH 2/2] 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 <errno.h>. (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 <br...@clisp.org> + + 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 <errno.h>. + (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 <br...@clisp.org> 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 @@ @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 <stdlib.h> +#include <errno.h> + 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.34.1