]> Savannah Git Hosting - gnulib.git/commitdiff
posix_memalign: check for GNU behavior with size 0
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 30 Oct 2024 19:47:02 +0000 (12:47 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 30 Oct 2024 19:50:24 +0000 (12:50 -0700)
* 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
doc/posix-functions/posix_memalign.texi
lib/posix_memalign.c
m4/posix_memalign.m4
modules/posix_memalign
tests/test-posix_memalign.c

index 61296ba7794bf8fb5ab10f20a3d612489f892f23..6ce890f5ccc7e075a1a675858ee9febb8f0313b9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2024-10-30  Paul Eggert  <eggert@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
index 6585513548c44d393626aa061d5fb9e7b14c931a..d802fd6ebe72e8fb9d0d3b63738adc820304d03c 100644 (file)
@@ -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
index 6a13c56710207d3acc8a8811824cb9a5a3fff630..6dd713bdb5297a96a58ececaca13d2d05f0117b3 100644 (file)
 #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);
 }
index e814ec15604f097d026e14ba835dba716ee7c20d..37c40a528d0a80a09a40bafe1cd9651cb805682c 100644 (file)
@@ -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" ;;
index 0bcdf1841461b49ba8dc143833f688d703e368ba..e50e44ef239aa231449995372203d44b069a28a5 100644 (file)
@@ -7,6 +7,7 @@ m4/posix_memalign.m4
 
 Depends-on:
 extensions
+stdckdint        [test $REPLACE_POSIX_MEMALIGN = 1]
 stdlib
 
 configure.ac:
index 160e55b177da3774530f75d8fcf63410306e8e2b..b61ac4e2a008eaa05d6259469bcd1f6cf2767a1d 100644 (file)
@@ -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)];