git: 26bf9fc3a402 - main - libc: Fix GCC pointer semantics for atomic_fetch_add/sub

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 20 Jun 2026 00:24:58 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=26bf9fc3a40275a7aca0ce1809751a90c84b643a

commit 26bf9fc3a40275a7aca0ce1809751a90c84b643a
Author:     Faraz Vahedi <kfv@kfv.io>
AuthorDate: 2026-05-08 02:54:23 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-06-20 00:23:29 +0000

    libc: Fix GCC pointer semantics for atomic_fetch_add/sub
    
    Correct the GCC implementation of `atomic_fetch_add_explicit()`
    and `atomic_fetch_sub_explicit()` for atomic pointer types.
    
    The previous implementation passed the operand directly to the
    builtins. For pointer objects, this could result in raw byte-wise
    address arithmetic rather than the required C atomic pointer
    semantics, where the operand is interpreted as a `ptrdiff_t`
    element count.
    
    As a result, operations such as `atomic_fetch_sub_explicit(&p, 2, ...)`
    could produce an incorrect post-operation pointer value.
    
    Fix this by applying pointer scaling in the GCC path before invoking
    the builtin, mirroring the existing legacy fallback implementation.
    Pointer operands are now scaled by the size of the pointed-to type,
    while integer atomic behaviour remains unchanged.
    
    Signed-off-by: Faraz Vahedi <kfv@kfv.io>
    Reviewed by: imp
    Pull Request: https://github.com/freebsd/freebsd-src/pull/2185
---
 sys/sys/stdatomic.h | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/sys/sys/stdatomic.h b/sys/sys/stdatomic.h
index c0cbb7f785b5..a3d1f2cd4aeb 100644
--- a/sys/sys/stdatomic.h
+++ b/sys/sys/stdatomic.h
@@ -270,6 +270,8 @@ typedef _Atomic(__uintmax_t)		atomic_uintmax_t;
 #define	atomic_fetch_and_explicit(object, operand, order)		\
 	__c11_atomic_fetch_and(object, operand, order)
 #elif defined(__GNUC_ATOMICS)
+#define	__atomic_apply_stride(object, operand)				\
+	(((__typeof__(*(object)))0) + (operand))
 #define	atomic_store_explicit(object, desired, order)			\
 	__atomic_store_n(object, desired, order)
 #define	atomic_load_explicit(object, order)				\
@@ -285,9 +287,11 @@ typedef _Atomic(__uintmax_t)		atomic_uintmax_t;
 	__atomic_compare_exchange_n(object, expected,			\
 	    desired, 1, success, failure)
 #define	atomic_fetch_add_explicit(object, operand, order)		\
-	__atomic_fetch_add(object, operand, order)
+	__atomic_fetch_add(object,					\
+	    __atomic_apply_stride(object, operand), order)
 #define	atomic_fetch_sub_explicit(object, operand, order)		\
-	__atomic_fetch_sub(object, operand, order)
+	__atomic_fetch_sub(object,					\
+	    __atomic_apply_stride(object, operand), order)
 #define	atomic_fetch_or_explicit(object, operand, order)		\
 	__atomic_fetch_or(object, operand, order)
 #define	atomic_fetch_xor_explicit(object, operand, order)		\