From c25de3a3c51e3d27133947a3d943c2a2127445d5 Mon Sep 17 00:00:00 2001 From: jhb Date: Mon, 6 Aug 2018 23:51:08 +0000 Subject: [PATCH] Make the system C11 atomics headers fully compatible with external GCC. The and headers already included support for C11 atomics via intrinsincs in modern versions of GCC, but these versions tried to "hide" atomic variables inside a wrapper structure. This wrapper is not compatible with GCC's internal header, so that if GCC's was used together with , use of C11 atomics would fail to compile. Fix this by not hiding atomic variables in a structure for modern versions of GCC. The headers already avoid using a wrapper structure on clang. Note that this wrapper was only used if C11 was not enabled (e.g. via -std=c99), so this also fixes compile failures if a modern version of GCC was used with -std=c11 but with FreeBSD's instead of GCC's and this change fixes that case as well. Reported by: Mark Millard Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D16585 --- newlib/libc/include/stdatomic.h | 25 +++++++++++-------------- newlib/libc/include/sys/cdefs.h | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/newlib/libc/include/stdatomic.h b/newlib/libc/include/stdatomic.h index 09c0cf73e..1441c9e3b 100644 --- a/newlib/libc/include/stdatomic.h +++ b/newlib/libc/include/stdatomic.h @@ -169,12 +169,9 @@ atomic_signal_fence(memory_order __order __unused) /* Atomics in kernelspace are always lock-free. */ #define atomic_is_lock_free(obj) \ ((void)(obj), (_Bool)1) -#elif defined(__CLANG_ATOMICS) +#elif defined(__CLANG_ATOMICS) || defined(__GNUC_ATOMICS) #define atomic_is_lock_free(obj) \ __atomic_is_lock_free(sizeof(*(obj)), obj) -#elif defined(__GNUC_ATOMICS) -#define atomic_is_lock_free(obj) \ - __atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val) #else #define atomic_is_lock_free(obj) \ ((void)(obj), sizeof((obj)->__val) <= sizeof(void *)) @@ -260,28 +257,28 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t; #elif defined(__GNUC_ATOMICS) #define atomic_compare_exchange_strong_explicit(object, expected, \ desired, success, failure) \ - __atomic_compare_exchange_n(&(object)->__val, expected, \ + __atomic_compare_exchange_n(object, expected, \ desired, 0, success, failure) #define atomic_compare_exchange_weak_explicit(object, expected, \ desired, success, failure) \ - __atomic_compare_exchange_n(&(object)->__val, expected, \ + __atomic_compare_exchange_n(object, expected, \ desired, 1, success, failure) #define atomic_exchange_explicit(object, desired, order) \ - __atomic_exchange_n(&(object)->__val, desired, order) + __atomic_exchange_n(object, desired, order) #define atomic_fetch_add_explicit(object, operand, order) \ - __atomic_fetch_add(&(object)->__val, operand, order) + __atomic_fetch_add(object, operand, order) #define atomic_fetch_and_explicit(object, operand, order) \ - __atomic_fetch_and(&(object)->__val, operand, order) + __atomic_fetch_and(object, operand, order) #define atomic_fetch_or_explicit(object, operand, order) \ - __atomic_fetch_or(&(object)->__val, operand, order) + __atomic_fetch_or(object, operand, order) #define atomic_fetch_sub_explicit(object, operand, order) \ - __atomic_fetch_sub(&(object)->__val, operand, order) + __atomic_fetch_sub(object, operand, order) #define atomic_fetch_xor_explicit(object, operand, order) \ - __atomic_fetch_xor(&(object)->__val, operand, order) + __atomic_fetch_xor(object, operand, order) #define atomic_load_explicit(object, order) \ - __atomic_load_n(&(object)->__val, order) + __atomic_load_n(object, order) #define atomic_store_explicit(object, desired, order) \ - __atomic_store_n(&(object)->__val, desired, order) + __atomic_store_n(object, desired, order) #else #define __atomic_apply_stride(object, operand) \ (((__typeof__((object)->__val))0) + (operand)) diff --git a/newlib/libc/include/sys/cdefs.h b/newlib/libc/include/sys/cdefs.h index ccb47ea40..9a0466fff 100644 --- a/newlib/libc/include/sys/cdefs.h +++ b/newlib/libc/include/sys/cdefs.h @@ -288,7 +288,7 @@ #endif #if !defined(__cplusplus) && !__has_extension(c_atomic) && \ - !__has_extension(cxx_atomic) + !__has_extension(cxx_atomic) && !__GNUC_PREREQ__(4, 7) /* * No native support for _Atomic(). Place object in structure to prevent * most forms of direct non-atomic access. -- 2.43.5