+2024-11-04 Bruno Haible <bruno@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 <bruno@clisp.org>
tests: Add comments.
@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}
/* 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;
+ }
}
# 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,
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(
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
])
])
Depends-on:
extensions
stdlib
+malloc-posix [test $REPLACE_ALIGNED_ALLOC = 1]
configure.ac:
gl_FUNC_ALIGNED_ALLOC