diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -1541,7 +1541,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) { - if (this != &__u) + if (this != _VSTD::addressof(__u)) { __copy_assign_alloc(__u); hash_function() = __u.hash_function(); diff --git a/libcxx/include/__tree b/libcxx/include/__tree --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -1612,7 +1612,7 @@ __tree<_Tp, _Compare, _Allocator>& __tree<_Tp, _Compare, _Allocator>::operator=(const __tree& __t) { - if (this != &__t) + if (this != _VSTD::addressof(__t)) { value_comp() = __t.value_comp(); __copy_assign_alloc(__t); diff --git a/libcxx/include/deque b/libcxx/include/deque --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -1649,7 +1649,7 @@ deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(const deque& __c) { - if (this != &__c) + if (this != _VSTD::addressof(__c)) { __copy_assign_alloc(__c); assign(__c.begin(), __c.end()); diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -990,7 +990,7 @@ forward_list<_Tp, _Alloc>& forward_list<_Tp, _Alloc>::operator=(const forward_list& __x) { - if (this != &__x) + if (this != _VSTD::addressof(__x)) { base::__copy_assign_alloc(__x); assign(__x.begin(), __x.end()); diff --git a/libcxx/include/list b/libcxx/include/list --- a/libcxx/include/list +++ b/libcxx/include/list @@ -1392,7 +1392,7 @@ list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list& __c) { - if (this != &__c) + if (this != _VSTD::addressof(__c)) { base::__copy_assign_alloc(__c); assign(__c.begin(), __c.end()); diff --git a/libcxx/include/map b/libcxx/include/map --- a/libcxx/include/map +++ b/libcxx/include/map @@ -1036,7 +1036,7 @@ #ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else - if (this != &__m) { + if (this != _VSTD::addressof(__m)) { __tree_.clear(); __tree_.value_comp() = __m.__tree_.value_comp(); __tree_.__copy_assign_alloc(__m.__tree_); @@ -1820,7 +1820,7 @@ #ifndef _LIBCPP_CXX03_LANG __tree_ = __m.__tree_; #else - if (this != &__m) { + if (this != _VSTD::addressof(__m)) { __tree_.clear(); __tree_.value_comp() = __m.__tree_.value_comp(); __tree_.__copy_assign_alloc(__m.__tree_); diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -1056,7 +1056,7 @@ #ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else - if (this != &__u) { + if (this != _VSTD::addressof(__u)) { __table_.clear(); __table_.hash_function() = __u.__table_.hash_function(); __table_.key_eq() = __u.__table_.key_eq(); @@ -1988,7 +1988,7 @@ #ifndef _LIBCPP_CXX03_LANG __table_ = __u.__table_; #else - if (this != &__u) { + if (this != _VSTD::addressof(__u)) { __table_.clear(); __table_.hash_function() = __u.__table_.hash_function(); __table_.key_eq() = __u.__table_.key_eq(); diff --git a/libcxx/include/valarray b/libcxx/include/valarray --- a/libcxx/include/valarray +++ b/libcxx/include/valarray @@ -3048,7 +3048,7 @@ valarray<_Tp>& valarray<_Tp>::operator=(const valarray& __v) { - if (this != &__v) + if (this != _VSTD::addressof(__v)) return __assign_range(__v.__begin_, __v.__end_); return *this; } diff --git a/libcxx/include/vector b/libcxx/include/vector --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -1406,7 +1406,7 @@ vector<_Tp, _Allocator>& vector<_Tp, _Allocator>::operator=(const vector& __x) { - if (this != &__x) + if (this != _VSTD::addressof(__x)) { __base::__copy_assign_alloc(__x); assign(__x.__begin_, __x.__end_); @@ -2859,7 +2859,7 @@ vector& vector::operator=(const vector& __v) { - if (this != &__v) + if (this != _VSTD::addressof(__v)) { __copy_assign_alloc(__v); if (__v.__size_) diff --git a/libcxx/test/std/containers/associative/map/map.cons/copy_assign.addressof.compile.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/copy_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.cons/copy_assign.addressof.compile.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class map + +// map& operator=(const map& m); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + { + std::map mo; + std::map m; + m = mo; + } + { + std::map mo; + std::map m; + m = mo; + } +} diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/copy_assign.addressof.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/copy_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/copy_assign.addressof.compile.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class multimap + +// multimap& operator=(const multimap& m); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + { + std::multimap mo; + std::multimap m; + m = mo; + } + { + std::multimap mo; + std::multimap m; + m = mo; + } +} diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/copy_assign.addressof.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/copy_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/copy_assign.addressof.compile.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class multiset + +// multiset& operator=(const multiset& s); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::multiset so; + std::multiset s; + s = so; +} diff --git a/libcxx/test/std/containers/associative/set/set.cons/copy_assign.addressof.compile.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/copy_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/set/set.cons/copy_assign.addressof.compile.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// class set + +// set& operator=(const set& s); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::set so; + std::set s; + s = so; +} diff --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// priority_queue& operator=(const priority_queue&) = default; + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::priority_queue pqo; + std::priority_queue pq; + pq = pqo; +} diff --git a/libcxx/test/std/containers/container.adaptors/queue/queue.defn/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.defn/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/container.adaptors/queue/queue.defn/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// queue& operator=(const queue& q); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::queue qo; + std::queue q; + q = qo; +} diff --git a/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/array.cons/implicit_copy.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// implicitly generated array assignment operators + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::array ao; + std::array a; + a = ao; +} diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/deque/deque.cons/move_assign.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// deque& operator=(deque&& c); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::deque dqo; + std::deque dq; + dq = dqo; +} diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// forward_list& operator=(const forward_list& x); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::forward_list lo; + std::forward_list l; + l = lo; +} diff --git a/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/list/list.cons/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Guard the debug iterators against ADL-hijacking. +// XFAIL: LIBCXX-DEBUG-FIXME + +// + +// list& operator=(const list& c); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::list lo; + std::list l; + l = lo; +} diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// vector& operator=(const vector& c); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::vector vo; + std::vector v; + v = vo; +} diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Guard the debug iterators against ADL-hijacking. +// XFAIL: LIBCXX-DEBUG-FIXME + +// + +// template , class Pred = equal_to, +// class Alloc = allocator>> +// class unordered_map + +// unordered_map& operator=(const unordered_map& u); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + { + std::unordered_map mo; + std::unordered_map m; + m = mo; + } + { + std::unordered_map mo; + std::unordered_map m; + m = mo; + } +} diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Guard the debug iterators against ADL-hijacking. +// XFAIL: LIBCXX-DEBUG-FIXME + +// + +// template , class Pred = equal_to, +// class Alloc = allocator>> +// class unordered_multimap + +// unordered_multimap& operator=(const unordered_multimap& u); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + { + std::unordered_multimap mo; + std::unordered_multimap m; + m = mo; + } + { + std::unordered_multimap mo; + std::unordered_multimap m; + m = mo; + } +} diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Guard the debug iterators against ADL-hijacking. +// XFAIL: LIBCXX-DEBUG-FIXME + +// + +// template , class Pred = equal_to, +// class Alloc = allocator> +// class unordered_multiset + +// unordered_multiset& operator=(const unordered_multiset& u); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_multiset so; + std::unordered_multiset s; + s = so; +} diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.addressof.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/assign_copy.addressof.compile.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// Guard the debug iterators against ADL-hijacking. +// XFAIL: LIBCXX-DEBUG-FIXME + +// + +// template , class Pred = equal_to, +// class Alloc = allocator> +// class unordered_set + +// unordered_set& operator=(const unordered_set& u); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::unordered_set so; + std::unordered_set s; + s = so; +} diff --git a/libcxx/test/std/numerics/numarray/template.valarray/valarray.assign/value_assign.addressof.compile.pass.cpp b/libcxx/test/std/numerics/numarray/template.valarray/valarray.assign/value_assign.addressof.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/numarray/template.valarray/valarray.assign/value_assign.addressof.compile.pass.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// template class valarray; + +// valarray& operator=(const value_type& x); + +// Validate whether the container can be copy-assigned with an ADL-hijacking operator& + +#include + +#include "test_macros.h" +#include "operator_hijacker.h" + +void test() { + std::valarray vo; + std::valarray v; + v = vo; +} diff --git a/libcxx/test/support/operator_hijacker.h b/libcxx/test/support/operator_hijacker.h new file mode 100644 --- /dev/null +++ b/libcxx/test/support/operator_hijacker.h @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef SUPPORT_OPERATOR_HIJACKER_H +#define SUPPORT_OPERATOR_HIJACKER_H + +#include +#include + +#include "test_macros.h" + +/// Helper struct to test ADL-hijacking in containers. +/// +/// The class has some additional operations to be usable in all containers. +struct operator_hijacker { + bool operator<(const operator_hijacker&) const { return true; } + bool operator==(const operator_hijacker&) const { return true; } + + template + friend void operator&(T&&) = delete; + template + friend void operator,(T&&, U&&) = delete; + template + friend void operator&&(T&&, U&&) = delete; + template + friend void operator||(T&&, U&&) = delete; +}; + +template <> +struct std::hash { + size_t operator()(const operator_hijacker&) const { return 0; } +}; + +#endif // SUPPORT_OPERATOR_HIJACKER_H