diff --git a/libcxx/include/atomic b/libcxx/include/atomic --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -1681,16 +1681,10 @@ #ifndef _LIBCPP_CXX03_LANG __atomic_base(const __atomic_base&) = delete; - __atomic_base& operator=(const __atomic_base&) = delete; - __atomic_base& operator=(const __atomic_base&) volatile = delete; #else private: _LIBCPP_INLINE_VISIBILITY __atomic_base(const __atomic_base&); - _LIBCPP_INLINE_VISIBILITY - __atomic_base& operator=(const __atomic_base&); - _LIBCPP_INLINE_VISIBILITY - __atomic_base& operator=(const __atomic_base&) volatile; #endif }; @@ -1800,6 +1794,12 @@ _LIBCPP_INLINE_VISIBILITY _Tp operator=(_Tp __d) _NOEXCEPT {__base::store(__d); return __d;} + + // delete explicitly in the most derived class to satisfy the requirement + // that atomic (possibly volatile qualified) variables are not copyable + // For mor information see https://bugs.llvm.org/show_bug.cgi?id=41784 + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; // atomic @@ -1862,6 +1862,12 @@ _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} _LIBCPP_INLINE_VISIBILITY _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} + + // delete explicitly in the most derived class to satisfy the requirement + // that atomic (possibly volatile qualified) variables are not copyable + // For mor information see https://bugs.llvm.org/show_bug.cgi?id=41784 + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; // atomic_is_lock_free diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.ptr.volatile.verify.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.ptr.volatile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.ptr.volatile.verify.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// std::atomic + +// atomic& operator=( const atomic& ) volatile = delete; + +#include + +int main(int, char**) +{ + volatile std::atomic obj1; + std::atomic obj2; + obj1 = obj2; // expected-error {{overload resolution selected deleted operator '='}} +} diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.volatile.verify.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.volatile.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/copy.assign.volatile.verify.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// std::atomic + +// atomic& operator=( const atomic& ) volatile = delete; + +#include + +int main(int, char**) { + volatile std::atomic obj1; + std::atomic obj2; + obj1 = obj2; // expected-error {{overload resolution selected deleted operator '='}} +}