[libcxx-commits] [libcxx] f41f392 - [libc++] Fixes operator& hijacking atomic types.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Mon Feb 27 10:23:21 PST 2023


Author: Mark de Wever
Date: 2023-02-27T19:23:13+01:00
New Revision: f41f392520935ff78f211f48240c46d6c715fd13

URL: https://github.com/llvm/llvm-project/commit/f41f392520935ff78f211f48240c46d6c715fd13
DIFF: https://github.com/llvm/llvm-project/commit/f41f392520935ff78f211f48240c46d6c715fd13.diff

LOG: [libc++] Fixes operator& hijacking atomic types.

This uses std::addressof everywherein atomic. This is not strictly
needed for the integral and floating point specializations. They should
not be used by user defined types. But it's easier to fix everything.

Note these changes are made using a WIP clang-tidy plugin.

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D144786

Added: 
    libcxx/test/std/atomics/atomics.types.generic/general.compile.pass.cpp
    libcxx/test/std/atomics/atomics.types.generic/pointer.compile.pass.cpp

Modified: 
    libcxx/include/__atomic/atomic.h
    libcxx/include/__atomic/atomic_base.h
    libcxx/include/__atomic/atomic_sync.h
    libcxx/include/__atomic/cxx_atomic_impl.h
    libcxx/test/support/operator_hijacker.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index 57671c12c4e60..68df7f12c1e58 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -14,6 +14,7 @@
 #include <__atomic/cxx_atomic_impl.h>
 #include <__atomic/memory_order.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/is_function.h>
 #include <__type_traits/is_same.h>
 #include <__type_traits/remove_pointer.h>
@@ -82,28 +83,28 @@ struct atomic<_Tp*>
     _Tp* fetch_add(ptr
diff _t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
         // __atomic_fetch_add accepts function pointers, guard against them.
         static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
+        return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
     }
 
     _LIBCPP_HIDE_FROM_ABI
     _Tp* fetch_add(ptr
diff _t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
         // __atomic_fetch_add accepts function pointers, guard against them.
         static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);
+        return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
     }
 
     _LIBCPP_HIDE_FROM_ABI
     _Tp* fetch_sub(ptr
diff _t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
         // __atomic_fetch_add accepts function pointers, guard against them.
         static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
+        return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
     }
 
     _LIBCPP_HIDE_FROM_ABI
     _Tp* fetch_sub(ptr
diff _t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
         // __atomic_fetch_add accepts function pointers, guard against them.
         static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
-        return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);
+        return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
     }
 
     _LIBCPP_HIDE_FROM_ABI
@@ -160,7 +161,7 @@ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
 void
 atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
 {
-    std::__cxx_atomic_init(&__o->__a_, __d);
+    std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
 }
 
 template <class _Tp>
@@ -168,7 +169,7 @@ _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI
 void
 atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
 {
-    std::__cxx_atomic_init(&__o->__a_, __d);
+    std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
 }
 
 // atomic_store

diff  --git a/libcxx/include/__atomic/atomic_base.h b/libcxx/include/__atomic/atomic_base.h
index 413f096a6702f..7a9ba78433194 100644
--- a/libcxx/include/__atomic/atomic_base.h
+++ b/libcxx/include/__atomic/atomic_base.h
@@ -16,6 +16,7 @@
 #include <__atomic/memory_order.h>
 #include <__availability>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/is_integral.h>
 #include <__type_traits/is_nothrow_default_constructible.h>
 #include <__type_traits/is_same.h>
@@ -42,81 +43,87 @@ struct __atomic_base  // false
     _LIBCPP_HIDE_FROM_ABI
     bool is_lock_free() const _NOEXCEPT
         {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
-    _LIBCPP_HIDE_FROM_ABI
-    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-        {std::__cxx_atomic_store(&__a_, __d, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
-        {std::__cxx_atomic_store(&__a_, __d, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-        {return std::__cxx_atomic_load(&__a_, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
-        {return std::__cxx_atomic_load(&__a_, __m);}
+    _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
+        _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
+      std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
+        _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
+      std::__cxx_atomic_store(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
+        _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
+      return std::__cxx_atomic_load(std::addressof(__a_), __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
+        _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
+      return std::__cxx_atomic_load(std::addressof(__a_), __m);
+    }
     _LIBCPP_HIDE_FROM_ABI
     operator _Tp() const volatile _NOEXCEPT {return load();}
     _LIBCPP_HIDE_FROM_ABI
     operator _Tp() const _NOEXCEPT          {return load();}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_exchange(&__a_, __d, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __s, memory_order __f) volatile _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __s, memory_order __f) _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __s, memory_order __f) _NOEXCEPT
-      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_weak(_Tp& __e, _Tp __d,
-                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    bool compare_exchange_strong(_Tp& __e, _Tp __d,
-                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
-
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
-        {std::__cxx_atomic_wait(&__a_, __v, __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
-        {std::__cxx_atomic_wait(&__a_, __v, __m);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT
-        {std::__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT
-        {std::__cxx_atomic_notify_one(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT
-        {std::__cxx_atomic_notify_all(&__a_);}
-    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT
-        {std::__cxx_atomic_notify_all(&__a_);}
+    _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
+        _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI bool
+    compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);
+    }
+
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const
+        volatile _NOEXCEPT {
+      std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
+    wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {
+      std::__cxx_atomic_wait(std::addressof(__a_), __v, __m);
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {
+      std::__cxx_atomic_notify_one(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT {
+      std::__cxx_atomic_notify_one(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {
+      std::__cxx_atomic_notify_all(std::addressof(__a_));
+    }
+    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT {
+      std::__cxx_atomic_notify_all(std::addressof(__a_));
+    }
 
 #if _LIBCPP_STD_VER >= 20
     _LIBCPP_HIDE_FROM_ABI constexpr
@@ -151,36 +158,36 @@ struct __atomic_base<_Tp, true>
     _LIBCPP_HIDE_FROM_ABI
     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
 
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
-        {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
-    _LIBCPP_HIDE_FROM_ABI
-    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
-        {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
+      return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
+    }
+    _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
+      return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);
+    }
 
     _LIBCPP_HIDE_FROM_ABI
     _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}

diff  --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h
index 986c02c1b2265..114bc50d5c8a1 100644
--- a/libcxx/include/__atomic/atomic_sync.h
+++ b/libcxx/include/__atomic/atomic_sync.h
@@ -15,6 +15,7 @@
 #include <__availability>
 #include <__chrono/duration.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__thread/poll_with_backoff.h>
 #include <__threading_support>
 #include <__type_traits/decay.h>
@@ -84,7 +85,7 @@ _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
 
 template <typename _Tp> _LIBCPP_HIDE_FROM_ABI
 bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
-    return std::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
+    return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0;
 }
 
 template <class _Atp, class _Tp>

diff  --git a/libcxx/include/__atomic/cxx_atomic_impl.h b/libcxx/include/__atomic/cxx_atomic_impl.h
index 2b700a2854981..167cee7f0bdec 100644
--- a/libcxx/include/__atomic/cxx_atomic_impl.h
+++ b/libcxx/include/__atomic/cxx_atomic_impl.h
@@ -12,6 +12,7 @@
 #include <__atomic/is_always_lock_free.h>
 #include <__atomic/memory_order.h>
 #include <__config>
+#include <__memory/addressof.h>
 #include <__type_traits/conditional.h>
 #include <__type_traits/is_assignable.h>
 #include <__type_traits/is_trivially_copyable.h>
@@ -39,9 +40,9 @@ __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
 template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI
 typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
 __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
-  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
+  volatile char* __to         = reinterpret_cast<volatile char*>(std::addressof(__a_value));
   volatile char* __end = __to + sizeof(_Tp);
-  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
+  volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));
   while (__to != __end)
     *__to++ = *__from++;
 }
@@ -110,16 +111,14 @@ template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
                         memory_order __order) {
-  __atomic_store(&__a->__a_value, &__val,
-                 __to_gcc_order(__order));
+  __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
                         memory_order __order) {
-  __atomic_store(&__a->__a_value, &__val,
-                 __to_gcc_order(__order));
+  __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
 }
 
 template <typename _Tp>
@@ -127,8 +126,7 @@ _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
                       memory_order __order) {
   _Tp __ret;
-  __atomic_load(&__a->__a_value, &__ret,
-                __to_gcc_order(__order));
+  __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
   return __ret;
 }
 
@@ -136,8 +134,7 @@ template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
   _Tp __ret;
-  __atomic_load(&__a->__a_value, &__ret,
-                __to_gcc_order(__order));
+  __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
   return __ret;
 }
 
@@ -146,8 +143,8 @@ _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
                           _Tp __value, memory_order __order) {
   _Tp __ret;
-  __atomic_exchange(&__a->__a_value, &__value, &__ret,
-                    __to_gcc_order(__order));
+  __atomic_exchange(
+      std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
   return __ret;
 }
 
@@ -156,8 +153,8 @@ _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
                           memory_order __order) {
   _Tp __ret;
-  __atomic_exchange(&__a->__a_value, &__value, &__ret,
-                    __to_gcc_order(__order));
+  __atomic_exchange(
+      std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
   return __ret;
 }
 
@@ -166,10 +163,13 @@ _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_strong(
     volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
     memory_order __success, memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   false,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      false,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
 }
 
 template <typename _Tp>
@@ -177,10 +177,13 @@ _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_strong(
     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
     memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   false,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      false,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
 }
 
 template <typename _Tp>
@@ -188,10 +191,13 @@ _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_weak(
     volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
     memory_order __success, memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   true,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      true,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
 }
 
 template <typename _Tp>
@@ -199,10 +205,13 @@ _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_weak(
     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
     memory_order __failure) {
-  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
-                                   true,
-                                   __to_gcc_order(__success),
-                                   __to_gcc_failure_order(__failure));
+  return __atomic_compare_exchange(
+      std::addressof(__a->__a_value),
+      __expected,
+      std::addressof(__value),
+      true,
+      __to_gcc_order(__success),
+      __to_gcc_failure_order(__failure));
 }
 
 template <typename _Tp>
@@ -222,80 +231,70 @@ template <typename _Tp, typename _Td>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
                            _Td __delta, memory_order __order) {
-  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
 }
 
 template <typename _Tp, typename _Td>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
                            memory_order __order) {
-  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
 }
 
 template <typename _Tp, typename _Td>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
                            _Td __delta, memory_order __order) {
-  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
 }
 
 template <typename _Tp, typename _Td>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
                            memory_order __order) {
-  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
                            _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_and(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
                            _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_and(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
                           _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_or(&__a->__a_value, __pattern,
-                           __to_gcc_order(__order));
+  return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
                           memory_order __order) {
-  return __atomic_fetch_or(&__a->__a_value, __pattern,
-                           __to_gcc_order(__order));
+  return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
                            _Tp __pattern, memory_order __order) {
-  return __atomic_fetch_xor(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 template <typename _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
                            memory_order __order) {
-  return __atomic_fetch_xor(&__a->__a_value, __pattern,
-                            __to_gcc_order(__order));
+  return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
 }
 
 #define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
@@ -331,47 +330,51 @@ void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
-    __c11_atomic_init(&__a->__a_value, __val);
+    __c11_atomic_init(std::addressof(__a->__a_value), __val);
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
-    __c11_atomic_init(&__a->__a_value, __val);
+    __c11_atomic_init(std::addressof(__a->__a_value), __val);
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
-    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
+    __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
-    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
+    __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
     using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
-    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
+    return __c11_atomic_load(
+        const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
     using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
-    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
+    return __c11_atomic_load(
+        const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
+    return __c11_atomic_exchange(
+        std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
+    return __c11_atomic_exchange(
+        std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
 }
 
 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
@@ -384,99 +387,133 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(m
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+  return __c11_atomic_compare_exchange_strong(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+  return __c11_atomic_compare_exchange_strong(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+  return __c11_atomic_compare_exchange_weak(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
+  return __c11_atomic_compare_exchange_weak(
+      std::addressof(__a->__a_value),
+      __expected,
+      __value,
+      static_cast<__memory_order_underlying_t>(__success),
+      static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptr
diff _t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptr
diff _t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_add(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptr
diff _t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptr
diff _t __delta, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_sub(
+      std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_and(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_and(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_or(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_or(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_xor(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 template<class _Tp>
 _LIBCPP_HIDE_FROM_ABI
 _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
-    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
+  return __c11_atomic_fetch_xor(
+      std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
 }
 
 #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP

diff  --git a/libcxx/test/std/atomics/atomics.types.generic/general.compile.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/general.compile.pass.cpp
new file mode 100644
index 0000000000000..6a3d23f2fa600
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.generic/general.compile.pass.cpp
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// This test requires the dylib support introduced in D68480, which shipped in macOS 11.0.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+
+// <atomic>
+
+// Tests the basic features and makes sure they work with a hijacking operator&.
+
+//  template<class T> struct atomic {
+//    using value_type = T;
+//
+//    static constexpr bool is_always_lock_free = implementation-defined;
+//    bool is_lock_free() const volatile noexcept;
+//    bool is_lock_free() const noexcept;
+//
+//    // [atomics.types.operations], operations on atomic types
+//    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
+//    constexpr atomic(T) noexcept;
+//    atomic(const atomic&) = delete;
+//    atomic& operator=(const atomic&) = delete;
+//    atomic& operator=(const atomic&) volatile = delete;
+//
+//    T load(memory_order = memory_order::seq_cst) const volatile noexcept;
+//    T load(memory_order = memory_order::seq_cst) const noexcept;
+//    operator T() const volatile noexcept;
+//    operator T() const noexcept;
+//    void store(T, memory_order = memory_order::seq_cst) volatile noexcept;
+//    void store(T, memory_order = memory_order::seq_cst) noexcept;
+//    T operator=(T) volatile noexcept;
+//    T operator=(T) noexcept;
+//
+//    T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept;
+//    T exchange(T, memory_order = memory_order::seq_cst) noexcept;
+//    bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept;
+//    bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept;
+//    bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept;
+//    bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept;
+//    bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
+//    bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept;
+//    bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
+//    bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept;
+//
+//    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
+//    void wait(T, memory_order = memory_order::seq_cst) const noexcept;
+//    void notify_one() volatile noexcept;
+//    void notify_one() noexcept;
+//    void notify_all() volatile noexcept;
+//    void notify_all() noexcept;
+//  };
+
+#include <atomic>
+#include <type_traits>
+
+#include "operator_hijacker.h"
+#include "test_macros.h"
+
+template <class T>
+void test() {
+  T a;
+  typename T::value_type v;
+#if TEST_STD_VER >= 20
+  std::memory_order m = std::memory_order::seq_cst;
+#else
+  std::memory_order m = std::memory_order_seq_cst;
+#endif
+
+  TEST_IGNORE_NODISCARD a.is_lock_free();
+
+  TEST_IGNORE_NODISCARD T();
+  TEST_IGNORE_NODISCARD T(v);
+
+  TEST_IGNORE_NODISCARD a.load();
+  TEST_IGNORE_NODISCARD static_cast<typename T::value_type>(a);
+  a.store(v);
+  a = v;
+
+  TEST_IGNORE_NODISCARD a.exchange(v);
+  TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v, m, m);
+  TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m, m);
+  TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v);
+  TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m);
+
+  a.wait(v);
+  a.notify_one();
+  a.notify_all();
+}
+
+void test() {
+  test<std::atomic<operator_hijacker>>();
+  test<volatile std::atomic<operator_hijacker>>();
+}

diff  --git a/libcxx/test/std/atomics/atomics.types.generic/pointer.compile.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/pointer.compile.pass.cpp
new file mode 100644
index 0000000000000..3393ee0f17b7f
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.generic/pointer.compile.pass.cpp
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// This test requires the dylib support introduced in D68480, which shipped in macOS 11.0.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+
+// <atomic>
+
+// Tests the basic features and makes sure they work with a hijacking operator&.
+
+//  template<class T> struct atomic<T*> {
+//    using value_type = T*;
+//    using 
diff erence_type = ptr
diff _t;
+//
+//    static constexpr bool is_always_lock_free = implementation-defined;
+//    bool is_lock_free() const volatile noexcept;
+//    bool is_lock_free() const noexcept;
+//
+//    constexpr atomic() noexcept;
+//    constexpr atomic(T*) noexcept;
+//    atomic(const atomic&) = delete;
+//    atomic& operator=(const atomic&) = delete;
+//    atomic& operator=(const atomic&) volatile = delete;
+//
+//    void store(T*, memory_order = memory_order::seq_cst) volatile noexcept;
+//    void store(T*, memory_order = memory_order::seq_cst) noexcept;
+//    T* operator=(T*) volatile noexcept;
+//    T* operator=(T*) noexcept;
+//    T* load(memory_order = memory_order::seq_cst) const volatile noexcept;
+//    T* load(memory_order = memory_order::seq_cst) const noexcept;
+//    operator T*() const volatile noexcept;
+//    operator T*() const noexcept;
+//
+//    T* exchange(T*, memory_order = memory_order::seq_cst) volatile noexcept;
+//    T* exchange(T*, memory_order = memory_order::seq_cst) noexcept;
+//    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
+//    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
+//    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
+//    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
+//    bool compare_exchange_weak(T*&, T*,
+//                               memory_order = memory_order::seq_cst) volatile noexcept;
+//    bool compare_exchange_weak(T*&, T*,
+//                               memory_order = memory_order::seq_cst) noexcept;
+//    bool compare_exchange_strong(T*&, T*,
+//                                 memory_order = memory_order::seq_cst) volatile noexcept;
+//    bool compare_exchange_strong(T*&, T*,
+//                                 memory_order = memory_order::seq_cst) noexcept;
+//
+//    T* fetch_add(ptr
diff _t, memory_order = memory_order::seq_cst) volatile noexcept;
+//    T* fetch_add(ptr
diff _t, memory_order = memory_order::seq_cst) noexcept;
+//    T* fetch_sub(ptr
diff _t, memory_order = memory_order::seq_cst) volatile noexcept;
+//    T* fetch_sub(ptr
diff _t, memory_order = memory_order::seq_cst) noexcept;
+//
+//    T* operator++(int) volatile noexcept;
+//    T* operator++(int) noexcept;
+//    T* operator--(int) volatile noexcept;
+//    T* operator--(int) noexcept;
+//    T* operator++() volatile noexcept;
+//    T* operator++() noexcept;
+//    T* operator--() volatile noexcept;
+//    T* operator--() noexcept;
+//    T* operator+=(ptr
diff _t) volatile noexcept;
+//    T* operator+=(ptr
diff _t) noexcept;
+//    T* operator-=(ptr
diff _t) volatile noexcept;
+//    T* operator-=(ptr
diff _t) noexcept;
+//
+//    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
+//    void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
+//    void notify_one() volatile noexcept;
+//    void notify_one() noexcept;
+//    void notify_all() volatile noexcept;
+//    void notify_all() noexcept;
+//  };
+
+#include <atomic>
+#include <type_traits>
+
+#include "operator_hijacker.h"
+#include "test_macros.h"
+
+template <class T>
+void test() {
+  T a;
+  typename T::value_type v = nullptr;
+#if TEST_STD_VER >= 20
+  std::memory_order m = std::memory_order::seq_cst;
+#else
+  std::memory_order m = std::memory_order_seq_cst;
+#endif
+
+  TEST_IGNORE_NODISCARD a.is_lock_free();
+
+  a.store(v);
+  a = v;
+  TEST_IGNORE_NODISCARD T();
+  TEST_IGNORE_NODISCARD T(v);
+  TEST_IGNORE_NODISCARD a.load();
+  TEST_IGNORE_NODISCARD static_cast<typename T::value_type>(a);
+  TEST_IGNORE_NODISCARD* a;
+
+  TEST_IGNORE_NODISCARD a.exchange(v);
+  TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v, m, m);
+  TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m, m);
+  TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v);
+  TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m);
+
+  TEST_IGNORE_NODISCARD a.fetch_add(0);
+  TEST_IGNORE_NODISCARD a.fetch_sub(0);
+
+  TEST_IGNORE_NODISCARD a++;
+  TEST_IGNORE_NODISCARD a--;
+  TEST_IGNORE_NODISCARD++ a;
+  TEST_IGNORE_NODISCARD-- a;
+  a += 0;
+  a -= 0;
+
+  a.wait(v);
+  a.notify_one();
+  a.notify_all();
+}
+
+void test() {
+  test<std::atomic<operator_hijacker*>>();
+  test<volatile std::atomic<operator_hijacker*>>();
+}

diff  --git a/libcxx/test/support/operator_hijacker.h b/libcxx/test/support/operator_hijacker.h
index 34be330b056ad..294d2e55879b7 100644
--- a/libcxx/test/support/operator_hijacker.h
+++ b/libcxx/test/support/operator_hijacker.h
@@ -31,6 +31,13 @@ struct operator_hijacker {
   friend void operator||(T&&, U&&) = delete;
 };
 
+static_assert(std::is_trivially_copyable<operator_hijacker>::value &&     //
+                  std::is_copy_constructible<operator_hijacker>::value && //
+                  std::is_move_constructible<operator_hijacker>::value && //
+                  std::is_copy_assignable<operator_hijacker>::value &&    //
+                  std::is_move_assignable<operator_hijacker>::value,      //
+              "does not satisfy the requirements for atomic<operator_hijacker>");
+
 template <>
 struct std::hash<operator_hijacker> {
   size_t operator()(const operator_hijacker&) const { return 0; }


        


More information about the libcxx-commits mailing list