Skip site navigation (1)Skip section navigation (2)


| raw e-mail | index | archive | help

The branch main has been updated by fuz:

URL: https://cgit.FreeBSD.org/src/commit/?id=6c57e368eb1777f6097158eeca2fcc175d068dba

commit 6c57e368eb1777f6097158eeca2fcc175d068dba
Author:     Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2025-11-10 17:54:41 +0000
Commit:     Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2025-11-12 12:23:09 +0000

    lib/libc: implement C23 memalignment()
    
    This new function computes the alignment of a pointer.
    It is part of ISO/IEC 9899:2024, the new C standard.
    If the pointer is a null pointer, null is returned.
    I have tried to write an implementation that can cope
    with traditional address-based architectures, even if
    size_t and uintptr_t are of different length.  Adjustments
    may be needed for CHERI though.
    
    A man page is provided, too.  No unit test for now.
    
    Reviewed by:    kib, imp, ziaee (manpages), pauamma@gundo.com
    Approved by:    markj (mentor)
    MFC after:      1 month
    Relnotes:       yes
    Differential Revision:  https://reviews.freebsd.org/D53673
---
 include/stdlib.h               |  8 +++++++
 lib/libc/stdlib/Makefile.inc   |  4 ++--
 lib/libc/stdlib/Symbol.map     |  1 +
 lib/libc/stdlib/memalignment.3 | 53 ++++++++++++++++++++++++++++++++++++++++++
 lib/libc/stdlib/memalignment.c | 28 ++++++++++++++++++++++
 5 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/include/stdlib.h b/include/stdlib.h
index 784cb63bfc5b..3e54b5feb6de 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -167,6 +167,14 @@ int	at_quick_exit(void (*)(void)) __noexcept;
 _Noreturn void
 	quick_exit(int) /* __noexcept -- not ready ABI issues? */;
 #endif /* __ISO_C_VISIBLE >= 2011 */
+
+/*
+ * C23 extensions
+ */
+#if __ISO_C_VISIBLE >= 2023
+size_t	memalignment(const void *) __pure2;
+#endif /* __ISO_C_VISIBLE >= 2023 */
+
 /*
  * Extensions made by POSIX relative to C.
  */
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index e7b9955b9646..b878a7625e9f 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -7,7 +7,7 @@ MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
 	div.c exit.c getenv.c getopt.c getopt_long.c \
 	getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \
 	hsearch_r.c imaxabs.c imaxdiv.c \
-	insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
+	insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c memalignment.c \
 	merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \
 	qsort_s.c quick_exit.c radixsort.c rand.c \
 	random.c reallocarray.c reallocf.c realpath.c recallocarray.c remque.c \
@@ -35,7 +35,7 @@ MAN+=	a64l.3 abort.3 abs.3 atexit.3 atof.3 \
 	atoi.3 atol.3 at_quick_exit.3 bsearch.3 \
 	div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
 	hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
-	lsearch.3 memory.3 ptsname.3 qsort.3 \
+	lsearch.3 memalignment.3 memory.3 ptsname.3 qsort.3 \
 	quick_exit.3 \
 	radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 realpath.3 \
 	set_constraint_handler_s.3 \
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 53d71bcafb7d..8b7e97c3cbdc 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -132,6 +132,7 @@ FBSD_1.8 {
 };
 
 FBSD_1.9 {
+	memalignment;
 	recallocarray;
 };
 
diff --git a/lib/libc/stdlib/memalignment.3 b/lib/libc/stdlib/memalignment.3
new file mode 100644
index 000000000000..4a2269a82c81
--- /dev/null
+++ b/lib/libc/stdlib/memalignment.3
@@ -0,0 +1,53 @@
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 10, 2025
+.Dt MEMALIGNMENT 3
+.Os
+.Sh NAME
+.Nm memalignment
+.Nd find the memory alignment of an object
+.Sh SYNOPSIS
+.Lb libc
+.In stdlib.h
+.Ft size_t
+.Fn memalignment "const void *ptr"
+.Sh DESCRIPTION
+The
+.Fn memalignment
+function determines the alignment of the object pointed to by
+.Fa ptr .
+This alignment is a power of\~2, and may be larger than the range
+supported by the
+.Sy alignof
+operator.
+The value returned can be compared to the result of
+.Sy alignof ,
+and if it is greater or equal, the alignment requirement of the operand
+is satisfied.
+.Sh RETURN VALUES
+Returns the alignment of
+.Fa ptr
+as a power of\~2.
+If
+.Fa ptr
+is a null pointer, an alignment of zero is returned.
+An alignment of zero indicates that the tested pointer cannot be used to
+access an object of any type.
+.Sh SEE ALSO
+.Xr aligned_alloc 3 ,
+.Xr posix_memalign 3
+.Sh STANDARDS
+The
+.Fn memalignment
+function conforms to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Fn memalignment
+function was added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/lib/libc/stdlib/memalignment.c b/lib/libc/stdlib/memalignment.c
new file mode 100644
index 000000000000..771ddc2f5253
--- /dev/null
+++ b/lib/libc/stdlib/memalignment.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+size_t
+memalignment(const void *p)
+{
+	uintptr_t align;
+
+	if (p == NULL)
+		return (0);
+
+	align = (uintptr_t)p;
+	align &= -align;
+
+#if UINTPTR_MAX > SIZE_MAX
+	/* if alignment overflows size_t, return maximum possible */
+	if (align > SIZE_MAX)
+		align = SIZE_MAX - SIZE_MAX/2;
+#endif
+
+	return (align);
+}