]> Savannah Git Hosting - gnulib.git/commitdiff
malloc etc. tests: use volatile more consistently
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 4 Nov 2024 17:38:03 +0000 (09:38 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 4 Nov 2024 17:40:29 +0000 (09:40 -0800)
Typically it’s ineffective to use ‘void *volatile p’
when testing malloc and similar functions, as the compiler
can optimize the call to malloc before assigning the result
to the volatile pointer variable.  Instead, be more systematic
about calling malloc through a volatile function pointer
so that the compiler cannot infer that it is a malloc call.
This fix can’t be done for alloca-like functions which may not
have a function address, so continue to trust to luck there.
* tests/test-aligned-malloc.c (aligned4_malloc, aligned4_free)
(aligned8_malloc, aligned8_free, aligned16_malloc)
(aligned16_free, aligned32_malloc, aligned32_free):
* tests/test-aligned_alloc.c (aligned_alloc):
* tests/test-calloc-gnu.c (calloc):
* tests/test-free.c (free):
* tests/test-malloc-gnu.c (malloc):
* tests/test-reallocarray.c (reallocarray):
Test indirectly, by calling through a volatile pointer.
* tests/test-aligned-malloc.c, tests/test-aligned_alloc.c:
* tests/test-calloc-gnu.c, tests/test-calloc-posix.c:
* tests/test-free.c, tests/test-malloc-gnu.c:
* tests/test-malloc-posix.c, tests/test-realloc-posix.c:
* tests/test-reallocarray.c:
(main) Don’t bother making data pointers olatile, as it’s ineffective.
* tests/test-calloc-gnu.c (identity):
* tests/test-free.c (get_errno, get_errno_func):
Remove; all uses removed.

ChangeLog
tests/test-aligned-malloc.c
tests/test-aligned_alloc.c
tests/test-calloc-gnu.c
tests/test-calloc-posix.c
tests/test-free.c
tests/test-malloc-gnu.c
tests/test-malloc-posix.c
tests/test-realloc-posix.c
tests/test-reallocarray.c

index 727df3dcb0c4d9182ca8d02fb39e37eab3dc4ef5..a2b5a45e3ecdf87d8ff6794f18e43543ccf2a1da 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2024-11-04  Paul Eggert  <eggert@cs.ucla.edu>
+
+       malloc etc. tests: use volatile more consistently
+       Typically it’s ineffective to use ‘void *volatile p’
+       when testing malloc and similar functions, as the compiler
+       can optimize the call to malloc before assigning the result
+       to the volatile pointer variable.  Instead, be more systematic
+       about calling malloc through a volatile function pointer
+       so that the compiler cannot infer that it is a malloc call.
+       This fix can’t be done for alloca-like functions which may not
+       have a function address, so continue to trust to luck there.
+       * tests/test-aligned-malloc.c (aligned4_malloc, aligned4_free)
+       (aligned8_malloc, aligned8_free, aligned16_malloc)
+       (aligned16_free, aligned32_malloc, aligned32_free):
+       * tests/test-aligned_alloc.c (aligned_alloc):
+       * tests/test-calloc-gnu.c (calloc):
+       * tests/test-free.c (free):
+       * tests/test-malloc-gnu.c (malloc):
+       * tests/test-reallocarray.c (reallocarray):
+       Test indirectly, by calling through a volatile pointer.
+       * tests/test-aligned-malloc.c, tests/test-aligned_alloc.c:
+       * tests/test-calloc-gnu.c, tests/test-calloc-posix.c:
+       * tests/test-free.c, tests/test-malloc-gnu.c:
+       * tests/test-malloc-posix.c, tests/test-realloc-posix.c:
+       * tests/test-reallocarray.c:
+       (main) Don’t bother making data pointers olatile, as it’s ineffective.
+       * tests/test-calloc-gnu.c (identity):
+       * tests/test-free.c (get_errno, get_errno_func):
+       Remove; all uses removed.
+
 2024-11-04  Bruno Haible  <bruno@clisp.org>
 
        aligned_alloc: Fix test failures on macOS, Solaris (regr. 2024-10-30).
index 573304bf10ede50f8ec73bc4b7c2cfd562a4e83c..519ceea511be31afd812971d2aee5826751740b2 100644 (file)
 #undef aligned_free
 #undef aligned_malloc
 #undef ALIGNMENT
+void *(*volatile my_aligned4_malloc) (size_t) = aligned4_malloc;
+#define aligned4_malloc my_aligned4_malloc
+void (*volatile my_aligned4_free) (void *) = aligned4_free;
+#define aligned4_free my_aligned4_free
 
 #define ALIGNMENT 8
 #define aligned_malloc aligned8_malloc
 #undef aligned_free
 #undef aligned_malloc
 #undef ALIGNMENT
+void *(*volatile my_aligned8_malloc) (size_t) = aligned8_malloc;
+#define aligned8_malloc my_aligned8_malloc
+void (*volatile my_aligned8_free) (void *) = aligned8_free;
+#define aligned8_free my_aligned8_free
 
 #define ALIGNMENT 16
 #define aligned_malloc aligned16_malloc
 #undef aligned_free
 #undef aligned_malloc
 #undef ALIGNMENT
+void *(*volatile my_aligned16_malloc) (size_t) = aligned16_malloc;
+#define aligned16_malloc my_aligned16_malloc
+void (*volatile my_aligned16_free) (void *) = aligned16_free;
+#define aligned16_free my_aligned16_free
 
 #define ALIGNMENT 32
 #define aligned_malloc aligned32_malloc
 #undef aligned_free
 #undef aligned_malloc
 #undef ALIGNMENT
+void *(*volatile my_aligned32_malloc) (size_t) = aligned32_malloc;
+#define aligned32_malloc my_aligned32_malloc
+void (*volatile my_aligned32_free) (void *) = aligned32_free;
+#define aligned32_free my_aligned32_free
 
 #include <string.h>
 
@@ -63,10 +79,10 @@ main (int argc, char *argv[])
 {
   static size_t sizes[] =
     { 13, 8, 17, 450, 320, 1, 99, 4, 15, 16, 2, 76, 37, 127, 2406, 641 };
-  void *volatile aligned4_blocks[SIZEOF (sizes)];
-  void *volatile aligned8_blocks[SIZEOF (sizes)];
-  void *volatile aligned16_blocks[SIZEOF (sizes)];
-  void *volatile aligned32_blocks[SIZEOF (sizes)];
+  void *aligned4_blocks[SIZEOF (sizes)];
+  void *aligned8_blocks[SIZEOF (sizes)];
+  void *aligned16_blocks[SIZEOF (sizes)];
+  void *aligned32_blocks[SIZEOF (sizes)];
   size_t i;
 
   for (i = 0; i < SIZEOF (sizes); i++)
index bf953fe85d1bdec3a9b566576c286077b1b32ed4..61ca73fe05d003d75e25359aea6e6f665a8908a6 100644 (file)
 
 #include "macros.h"
 
+void *(*volatile my_aligned_alloc) (size_t, size_t) = aligned_alloc;
+#undef aligned_alloc
+#define aligned_alloc my_aligned_alloc
+
 #define ROUNDUP(x,y) (((x) + (y) - 1) & - (y))
 
 int
@@ -40,12 +44,12 @@ main (int argc, char *argv[])
       /* Test also a zero size.  */
       0
     };
-  void *volatile aligned2_blocks[SIZEOF (sizes)];
-  void *volatile aligned4_blocks[SIZEOF (sizes)];
-  void *volatile aligned8_blocks[SIZEOF (sizes)];
-  void *volatile aligned16_blocks[SIZEOF (sizes)];
-  void *volatile aligned32_blocks[SIZEOF (sizes)];
-  void *volatile aligned64_blocks[SIZEOF (sizes)];
+  void *aligned2_blocks[SIZEOF (sizes)];
+  void *aligned4_blocks[SIZEOF (sizes)];
+  void *aligned8_blocks[SIZEOF (sizes)];
+  void *aligned16_blocks[SIZEOF (sizes)];
+  void *aligned32_blocks[SIZEOF (sizes)];
+  void *aligned64_blocks[SIZEOF (sizes)];
   size_t i;
 
   for (i = 0; i < SIZEOF (sizes); i++)
index c356dfdef76b9441b3850b034d1bb7c7cb3b3173..f19e13089fb742c5af7f0d93df6d909a4835557b 100644 (file)
 
 #include "macros.h"
 
-/* Return N.
-   Usual compilers are not able to infer something about the return value.  */
-static size_t
-identity (size_t n)
-{
-  unsigned int x = rand ();
-  unsigned int y = x * x * x * x;
-  x++; y |= x * x * x * x;
-  x++; y |= x * x * x * x;
-  x++; y |= x * x * x * x;
-  y = y >> 1;
-  y &= -y;
-  y -= 8;
-  /* At this point Y is zero but GCC doesn't infer this.  */
-  return n + y;
-}
+/* Work around clang bug
+   <https://github.com/llvm/llvm-project/issues/114772>.  */
+void *(*volatile my_calloc) (size_t, size_t) = calloc;
+#undef calloc
+#define calloc my_calloc
 
 int
 main ()
 {
   /* Check that calloc (0, 0) is not a NULL pointer.  */
   {
-    void * volatile p = calloc (0, 0);
+    void *p = calloc (0, 0);
     ASSERT (p != NULL);
     free (p);
   }
 
   /* Check that calloc fails when requested to allocate a block of memory
-     larger than PTRDIFF_MAX or SIZE_MAX bytes.
-     Use 'identity' to avoid a compiler warning from GCC 7.
-     'volatile' is needed to defeat an incorrect optimization by clang 10,
-     see <https://bugs.llvm.org/show_bug.cgi?id=46055>.  */
+     larger than PTRDIFF_MAX or SIZE_MAX bytes.  */
   {
     for (size_t n = 2; n != 0; n <<= 1)
       {
-        void *volatile p = calloc (PTRDIFF_MAX / n + 1, identity (n));
+        void *p = calloc (PTRDIFF_MAX / n + 1, n);
         ASSERT (p == NULL);
         ASSERT (errno == ENOMEM);
 
-        p = calloc (SIZE_MAX / n + 1, identity (n));
+        p = calloc (SIZE_MAX / n + 1, n);
         ASSERT (p == NULL);
         ASSERT (errno == ENOMEM);
       }
index 5fb5c3baa2870cbcd08cd938478e3b0fe02e5b3f..d0904aaacdfc4a19d720e5873dbea76e7eefc59c 100644 (file)
@@ -27,7 +27,8 @@
 
 /* Work around clang bug
    <https://github.com/llvm/llvm-project/issues/114772>.  */
-void *(* volatile my_calloc) (size_t, size_t) = calloc;
+void *(*volatile my_calloc) (size_t, size_t) = calloc;
+#undef calloc
 #define calloc my_calloc
 
 int
@@ -38,7 +39,7 @@ main ()
      nowadays where a 32-bit process can actually allocate 2 GiB of RAM.  */
   if (sizeof (size_t) >= 8)
     {
-      void *volatile p;
+      void *p;
 
       errno = 0;
       p = calloc (SIZE_MAX / 20, 2);
index b0c084da795e7718c7213b0c8ffbbd04f80e313e..bc972ac04b7ee86119065f0e3a116f81cf936f80 100644 (file)
    a GCC optimization.  Without it, when optimizing, GCC would "know" that errno
    is unchanged by calling free(ptr), when ptr was the result of a malloc(...)
    call in the same function.  */
-static int
-get_errno (void)
-{
-  volatile int err = errno;
-  return err;
-}
-
-static int (* volatile get_errno_func) (void) = get_errno;
+void (*volatile my_free) (void *) = free;
+#undef free
+#define free my_free
 
 int
 main ()
@@ -53,11 +48,11 @@ main ()
   {
     errno = 1789; /* Liberté, égalité, fraternité.  */
     free (NULL);
-    ASSERT_NO_STDIO (get_errno_func () == 1789);
+    ASSERT_NO_STDIO (errno == 1789);
   }
   { /* Small memory allocations.  */
     #define N 10000
-    void * volatile ptrs[N];
+    void *ptrs[N];
     size_t i;
     for (i = 0; i < N; i++)
       ptrs[i] = malloc (15);
@@ -65,13 +60,13 @@ main ()
       {
         errno = 1789;
         free (ptrs[i]);
-        ASSERT_NO_STDIO (get_errno_func () == 1789);
+        ASSERT_NO_STDIO (errno == 1789);
       }
     #undef N
   }
   { /* Medium memory allocations.  */
     #define N 1000
-    void * volatile ptrs[N];
+    void *ptrs[N];
     size_t i;
     for (i = 0; i < N; i++)
       ptrs[i] = malloc (729);
@@ -79,13 +74,13 @@ main ()
       {
         errno = 1789;
         free (ptrs[i]);
-        ASSERT_NO_STDIO (get_errno_func () == 1789);
+        ASSERT_NO_STDIO (errno == 1789);
       }
     #undef N
   }
   { /* Large memory allocations.  */
     #define N 10
-    void * volatile ptrs[N];
+    void *ptrs[N];
     size_t i;
     for (i = 0; i < N; i++)
       ptrs[i] = malloc (5318153);
@@ -93,7 +88,7 @@ main ()
       {
         errno = 1789;
         free (ptrs[i]);
-        ASSERT_NO_STDIO (get_errno_func () == 1789);
+        ASSERT_NO_STDIO (errno == 1789);
       }
     #undef N
   }
@@ -138,7 +133,7 @@ main ()
         {
           /* Do a large memory allocation.  */
           size_t big_size = 0x1000000;
-          void * volatile ptr = malloc (big_size - 0x100);
+          void *ptr = malloc (big_size - 0x100);
           char *ptr_aligned = (char *) ((uintptr_t) ptr & ~(pagesize - 1));
           /* This large memory allocation allocated a memory area
              from ptr_aligned to ptr_aligned + big_size.
@@ -171,7 +166,7 @@ main ()
                  which increases the number of VMAs by 1, which is supposed
                  to fail.  */
               free (ptr);
-              ASSERT_NO_STDIO (get_errno_func () == 1789);
+              ASSERT_NO_STDIO (errno == 1789);
             }
         }
     }
index 126b7a60fd9e37601dd665430749855b78596e71..ec500c7e23bc53d3785a78fdfba96512b69f1d41 100644 (file)
 
 #include "macros.h"
 
+/* Work around clang bug
+   <https://github.com/llvm/llvm-project/issues/114772>.  */
+void *(*volatile my_malloc) (size_t) = malloc;
+#undef malloc
+#define malloc my_malloc
+
 int
 main (int argc, _GL_UNUSED char **argv)
 {
   /* Check that malloc (0) is not a NULL pointer.  */
-  void *volatile p = malloc (0);
+  void *p = malloc (0);
   ASSERT (p != NULL);
   free (p);
 
index 191b9d1048eb3897555964f4678472f54f31acdf..05716d2e73a45821605a58e5459f9eec94efd459 100644 (file)
@@ -27,7 +27,8 @@
 
 /* Work around clang bug
    <https://github.com/llvm/llvm-project/issues/114772>.  */
-void *(* volatile my_malloc) (size_t) = malloc;
+void *(*volatile my_malloc) (size_t) = malloc;
+#undef malloc
 #define malloc my_malloc
 
 int
@@ -38,7 +39,7 @@ main ()
      nowadays where a 32-bit process can actually allocate 2 GiB of RAM.  */
   if (sizeof (size_t) >= 8)
     {
-      void *volatile p;
+      void *p;
 
       errno = 0;
       p = malloc (SIZE_MAX / 10);
index c6d62e1d30ddca893e687a562e46270158ad2e02..f5a84a60e7294c9ab117607ff7e26697123180b5 100644 (file)
 
 /* Work around clang bug
    <https://github.com/llvm/llvm-project/issues/114772>.  */
-void *(* volatile my_realloc) (void *, size_t) = realloc;
+void *(*volatile my_realloc) (void *, size_t) = realloc;
+#undef realloc
 #define realloc my_realloc
 
 int
 main (int argc, _GL_UNUSED char **argv)
 {
-  void *volatile p;
+  void *p;
 
   /* Check that realloc (NULL, 0) is not a NULL pointer.  */
   p = realloc (NULL, 0);
@@ -57,7 +58,7 @@ main (int argc, _GL_UNUSED char **argv)
   if (PTRDIFF_MAX < SIZE_MAX)
     {
       size_t one = argc != 12345;
-      void *volatile r = realloc (p, PTRDIFF_MAX + one);
+      void *r = realloc (p, PTRDIFF_MAX + one);
       ASSERT (r == NULL);
       /* Avoid a test failure due to glibc bug
          <https://sourceware.org/bugzilla/show_bug.cgi?id=27870>.  */
@@ -70,7 +71,7 @@ main (int argc, _GL_UNUSED char **argv)
      nowadays where a 32-bit process can actually allocate 2 GiB of RAM.  */
   if (sizeof (size_t) >= 8)
     {
-      void *volatile r;
+      void *r;
 
       errno = 0;
       r = realloc (p, SIZE_MAX / 10);
index 2748b982ca72c364cbc4d79f60652a9f24ee6788..e3c7bf0d0b9f40901f10d1817a6ff4a126d4d924 100644 (file)
@@ -27,6 +27,12 @@ SIGNATURE_CHECK (reallocarray, void *, (void *, size_t, size_t));
 
 #include "macros.h"
 
+/* Work around clang bug
+   <https://github.com/llvm/llvm-project/issues/114772>.  */
+void *(*volatile my_reallocarray) (void *, size_t, size_t) = reallocarray;
+#undef reallocarray
+#define reallocarray my_reallocarray
+
 int
 main ()
 {
@@ -34,7 +40,7 @@ main ()
      of memory larger than PTRDIFF_MAX or SIZE_MAX bytes.  */
   for (size_t n = 2; n != 0; n <<= 1)
     {
-      void *volatile p = NULL;
+      void *p = NULL;
 
       if (PTRDIFF_MAX / n + 1 <= SIZE_MAX)
         {