* lib/posix_memalign.c: Include stdckdint.h.
(posix_memalign): Test for overflow more straightforwardly,
and more portably to unlikely platforms where SIZE_MAX <= INT_MAX.
Treat a zero size as if it were alignment.
* m4/posix_memalign.m4 (gl_FUNC_POSIX_MEMALIGN):
* tests/test-posix_memalign.c (main):
Test zero size too.  Use volatile to avoid compiler optimizations.
* modules/posix_memalign (Depends-on): Add stdckdint.
---
 ChangeLog                               | 10 ++++++++++
 doc/posix-functions/posix_memalign.texi |  3 +++
 lib/posix_memalign.c                    | 13 +++++++------
 m4/posix_memalign.m4                    | 17 +++++++++++++----
 modules/posix_memalign                  |  1 +
 tests/test-posix_memalign.c             |  5 ++++-
 6 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 61296ba779..6ce890f5cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2024-10-30  Paul Eggert  <egg...@cs.ucla.edu>
 
+       posix_memalign: check for GNU behavior with size 0
+       * lib/posix_memalign.c: Include stdckdint.h.
+       (posix_memalign): Test for overflow more straightforwardly,
+       and more portably to unlikely platforms where SIZE_MAX <= INT_MAX.
+       Treat a zero size as if it were alignment.
+       * m4/posix_memalign.m4 (gl_FUNC_POSIX_MEMALIGN):
+       * tests/test-posix_memalign.c (main):
+       Test zero size too.  Use volatile to avoid compiler optimizations.
+       * modules/posix_memalign (Depends-on): Add stdckdint.
+
        aligned_alloc: check for GNU behavior with size 0
        If someone ever needs to distinguish between GNU and merely POSIX
        behavior we can split this into two modules, but for now just
diff --git a/doc/posix-functions/posix_memalign.texi 
b/doc/posix-functions/posix_memalign.texi
index 6585513548..d802fd6ebe 100644
--- a/doc/posix-functions/posix_memalign.texi
+++ b/doc/posix-functions/posix_memalign.texi
@@ -14,6 +14,9 @@ it is more portable to older systems that do not support C11.
 Portability problems fixed by Gnulib:
 @itemize
 @item
+This function returns a null pointer if the size argument is zero:
+AIX 7.3.
+@item
 This function produces misaligned results on some platforms:
 OpenBSD 6.1.
 @end itemize
diff --git a/lib/posix_memalign.c b/lib/posix_memalign.c
index 6a13c56710..6dd713bdb5 100644
--- a/lib/posix_memalign.c
+++ b/lib/posix_memalign.c
@@ -20,16 +20,17 @@
 #include <stdlib.h>
 
 #include <errno.h>
+#include <stdckdint.h>
 
 int
 posix_memalign (void **memptr, size_t alignment, size_t size)
 #undef posix_memalign
 {
-  /* Round up SIZE to the next multiple of ALIGNMENT, namely
-     (SIZE + ALIGNMENT - 1) & ~(ALIGNMENT - 1).  */
-  size += alignment - 1;
-  if (size >= alignment - 1) /* no overflow? */
-    return posix_memalign (memptr, alignment, size & ~(size_t)(alignment - 1));
-  else
+  /* Round SIZE up to the next multiple of ALIGNMENT.
+     However, treat a zero size as if it were ALIGNMENT.  */
+  size_t aligned_size;
+  if (ckd_add (&aligned_size, size, alignment - !!size))
     return ENOMEM;
+  aligned_size &= -alignment;
+  return posix_memalign (memptr, alignment, aligned_size);
 }
diff --git a/m4/posix_memalign.m4 b/m4/posix_memalign.m4
index e814ec1560..37c40a528d 100644
--- a/m4/posix_memalign.m4
+++ b/m4/posix_memalign.m4
@@ -1,5 +1,5 @@
 # posix_memalign.m4
-# serial 4
+# serial 5
 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,15 +18,22 @@ AC_DEFUN([gl_FUNC_POSIX_MEMALIGN],
   if test $ac_cv_func_posix_memalign = yes; then
     dnl On OpenBSD 6.1, posix_memalign (&p, 32, 2406) stores a pointer
     dnl that is not a multiple of 32.
-    AC_CACHE_CHECK([whether posix_memalign works for large alignments],
+    dnl On AIX 7.3, aligned_alloc with a zero size returns NULL.
+    AC_CACHE_CHECK(
+      [whether posix_memalign works for large alignment or zero size],
       [gl_cv_func_posix_memalign_works],
       [AC_RUN_IFELSE(
          [AC_LANG_PROGRAM(
             [[#include <stdlib.h>
-            ]],
+              /* Use pposix_memalign to test; 'volatile' prevents the compiler
+                 from optimizing the malloc call away.  */
+              int (*volatile pposix_memalign) (void **, size_t, size_t)
+                = posix_memalign;]],
             [[void *p;
+              if (pposix_memalign (&p, 0, sizeof (void *)) != 0)
+                return 1;
               if (32 % sizeof (void *) == 0
-                  && posix_memalign (&p, 32, 2406) == 0
+                  && pposix_memalign (&p, 32, 2406) == 0
                   && (unsigned long) p % 32 != 0)
                 return 1;
               return 0;
@@ -36,6 +43,8 @@ AC_DEFUN([gl_FUNC_POSIX_MEMALIGN],
          [gl_cv_func_posix_memalign_works=no],
          [case "$host_os" in
 changequote(,)dnl
+                     # Guess no on AIX.
+            aix*)    gl_cv_func_aligned_alloc_works="guessing no" ;;
                       # Guess no on OpenBSD through 6.1.
             openbsd[1-5].* | openbsd6.[01] | openbsd6.[01].*)
                       gl_cv_func_posix_memalign_works="guessing no" ;;
diff --git a/modules/posix_memalign b/modules/posix_memalign
index 0bcdf18414..e50e44ef23 100644
--- a/modules/posix_memalign
+++ b/modules/posix_memalign
@@ -7,6 +7,7 @@ m4/posix_memalign.m4
 
 Depends-on:
 extensions
+stdckdint        [test $REPLACE_POSIX_MEMALIGN = 1]
 stdlib
 
 configure.ac:
diff --git a/tests/test-posix_memalign.c b/tests/test-posix_memalign.c
index 160e55b177..b61ac4e2a0 100644
--- a/tests/test-posix_memalign.c
+++ b/tests/test-posix_memalign.c
@@ -33,7 +33,10 @@ 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 };
+    {
+      13, 8, 17, 450, 320, 1, 99, 4, 15, 16,
+      2, 76, 37, 127, 2406, 641, 5781, 0
+    };
   void *aligned2_blocks[SIZEOF (sizes)];
   void *aligned4_blocks[SIZEOF (sizes)];
   void *aligned8_blocks[SIZEOF (sizes)];
-- 
2.43.0


Reply via email to