Thanks, I looked for instances of similar problems and installed the
attached further patch.From 41be6842b56b2e83fb84be025a62c2dd1521af83 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Mon, 4 Nov 2024 09:38:03 -0800
Subject: [PATCH] malloc etc. tests: use volatile more consistently
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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 | 30 ++++++++++++++++++++++++++++++
tests/test-aligned-malloc.c | 24 ++++++++++++++++++++----
tests/test-aligned_alloc.c | 16 ++++++++++------
tests/test-calloc-gnu.c | 32 +++++++++-----------------------
tests/test-calloc-posix.c | 5 +++--
tests/test-free.c | 29 ++++++++++++-----------------
tests/test-malloc-gnu.c | 8 +++++++-
tests/test-malloc-posix.c | 5 +++--
tests/test-realloc-posix.c | 9 +++++----
tests/test-reallocarray.c | 8 +++++++-
10 files changed, 106 insertions(+), 60 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 727df3dcb0..a2b5a45e3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2024-11-04 Paul Eggert <egg...@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 <br...@clisp.org>
aligned_alloc: Fix test failures on macOS, Solaris (regr. 2024-10-30).
diff --git a/tests/test-aligned-malloc.c b/tests/test-aligned-malloc.c
index 573304bf10..519ceea511 100644
--- a/tests/test-aligned-malloc.c
+++ b/tests/test-aligned-malloc.c
@@ -29,6 +29,10 @@
#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
@@ -37,6 +41,10 @@
#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
@@ -45,6 +53,10 @@
#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
@@ -53,6 +65,10 @@
#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++)
diff --git a/tests/test-aligned_alloc.c b/tests/test-aligned_alloc.c
index bf953fe85d..61ca73fe05 100644
--- a/tests/test-aligned_alloc.c
+++ b/tests/test-aligned_alloc.c
@@ -28,6 +28,10 @@
#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++)
diff --git a/tests/test-calloc-gnu.c b/tests/test-calloc-gnu.c
index c356dfdef7..f19e13089f 100644
--- a/tests/test-calloc-gnu.c
+++ b/tests/test-calloc-gnu.c
@@ -24,46 +24,32 @@
#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);
}
diff --git a/tests/test-calloc-posix.c b/tests/test-calloc-posix.c
index 5fb5c3baa2..d0904aaacd 100644
--- a/tests/test-calloc-posix.c
+++ b/tests/test-calloc-posix.c
@@ -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);
diff --git a/tests/test-free.c b/tests/test-free.c
index b0c084da79..bc972ac04b 100644
--- a/tests/test-free.c
+++ b/tests/test-free.c
@@ -37,14 +37,9 @@
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);
}
}
}
diff --git a/tests/test-malloc-gnu.c b/tests/test-malloc-gnu.c
index 126b7a60fd..ec500c7e23 100644
--- a/tests/test-malloc-gnu.c
+++ b/tests/test-malloc-gnu.c
@@ -24,11 +24,17 @@
#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);
diff --git a/tests/test-malloc-posix.c b/tests/test-malloc-posix.c
index 191b9d1048..05716d2e73 100644
--- a/tests/test-malloc-posix.c
+++ b/tests/test-malloc-posix.c
@@ -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);
diff --git a/tests/test-realloc-posix.c b/tests/test-realloc-posix.c
index c6d62e1d30..f5a84a60e7 100644
--- a/tests/test-realloc-posix.c
+++ b/tests/test-realloc-posix.c
@@ -26,13 +26,14 @@
/* 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);
diff --git a/tests/test-reallocarray.c b/tests/test-reallocarray.c
index 2748b982ca..e3c7bf0d0b 100644
--- a/tests/test-reallocarray.c
+++ b/tests/test-reallocarray.c
@@ -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)
{
--
2.43.0