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

Reply via email to