From: Arthur O'Dwyer Date: Wed, 18 Nov 2020 23:54:38 +0000 (-0500) Subject: Revert "Revert "[libc++] ADL-proof by adding _VSTD:: qualification on calls."" X-Git-Tag: llvmorg-13-init~5465 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6e965df6054a4a6be53b3ba9ffa91ec7a0f9d072;p=platform%2Fupstream%2Fllvm.git Revert "Revert "[libc++] ADL-proof by adding _VSTD:: qualification on calls."" This reverts commit 620adacf87a376ec536ccc66af59df5bb4dc3b38. Fix: unsupport C++03 for the new test, define helpers before __swap_allocator (1) Add _VSTD:: qualification to __swap_allocator. (2) Add _VSTD:: qualification consistently to __to_address. (3) Add some more missing _VSTD:: to , with a regression test. This part is cleanup after d9a4f936d05. Note that a vector whose allocator actually runs afoul of any of these ADL calls will likely also run afoul of simple things like `v1 == v2` (which is also an ADL call). But, still, libc++ should be consistent in qualifying function calls wherever possible. Relevant blog post: https://quuxplusone.github.io/blog/2019/09/26/uglification-doesnt-stop-adl/ Differential Revision: https://reviews.llvm.org/D91708 --- diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 4e615d4..a004d59 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -2728,9 +2728,9 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) __u.__bucket_list_.reset(__npp); } _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); - __swap_allocator(__bucket_list_.get_deleter().__alloc(), + _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc()); - __swap_allocator(__node_alloc(), __u.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); __p2_.swap(__u.__p2_); __p3_.swap(__u.__p3_); diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index d212804..b1fbddc 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -279,7 +279,7 @@ void __split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) { while (__begin_ != __new_begin) - __alloc_traits::destroy(__alloc(), __to_address(__begin_++)); + __alloc_traits::destroy(__alloc(), _VSTD::__to_address(__begin_++)); } template @@ -296,7 +296,7 @@ void __split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT { while (__new_last != __end_) - __alloc_traits::destroy(__alloc(), __to_address(--__end_)); + __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__end_)); } template @@ -416,7 +416,7 @@ __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) _VSTD::swap(__begin_, __x.__begin_); _VSTD::swap(__end_, __x.__end_); _VSTD::swap(__end_cap(), __x.__end_cap()); - __swap_allocator(__alloc(), __x.__alloc()); + _VSTD::__swap_allocator(__alloc(), __x.__alloc()); } template diff --git a/libcxx/include/__tree b/libcxx/include/__tree index 4e131a1..404351b 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -1819,7 +1819,7 @@ __tree<_Tp, _Compare, _Allocator>::swap(__tree& __t) using _VSTD::swap; swap(__begin_node_, __t.__begin_node_); swap(__pair1_.first(), __t.__pair1_.first()); - __swap_allocator(__node_alloc(), __t.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __t.__node_alloc()); __pair3_.swap(__t.__pair3_); if (size() == 0) __begin_node() = __end_node(); diff --git a/libcxx/include/deque b/libcxx/include/deque index c2ea5f2..c66b102 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -1237,7 +1237,7 @@ __deque_base<_Tp, _Allocator>::swap(__deque_base& __c) __map_.swap(__c.__map_); _VSTD::swap(__start_, __c.__start_); _VSTD::swap(size(), __c.size()); - __swap_allocator(__alloc(), __c.__alloc()); + _VSTD::__swap_allocator(__alloc(), __c.__alloc()); } template @@ -2376,7 +2376,7 @@ deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), *__f); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), *__f); } } } @@ -2393,7 +2393,7 @@ deque<_Tp, _Allocator>::__append(size_type __n) for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_)); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_)); } } } @@ -2410,7 +2410,7 @@ deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) for (__deque_block_range __br : __deque_range(__base::end(), __base::end() + __n)) { _ConstructTransaction __tx(this, __br); for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { - __alloc_traits::construct(__a, std::__to_address(__tx.__pos_), __v); + __alloc_traits::construct(__a, _VSTD::__to_address(__tx.__pos_), __v); } } @@ -2708,7 +2708,7 @@ void deque<_Tp, _Allocator>::pop_front() { allocator_type& __a = __base::__alloc(); - __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() + __base::__start_ / __base::__block_size) + __base::__start_ % __base::__block_size)); --__base::size(); @@ -2723,7 +2723,7 @@ deque<_Tp, _Allocator>::pop_back() _LIBCPP_ASSERT(!empty(), "deque::pop_back called for empty deque"); allocator_type& __a = __base::__alloc(); size_type __p = __base::size() + __base::__start_ - 1; - __alloc_traits::destroy(__a, __to_address(*(__base::__map_.begin() + + __alloc_traits::destroy(__a, _VSTD::__to_address(*(__base::__map_.begin() + __p / __base::__block_size) + __p % __base::__block_size)); --__base::size(); diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index 3bd8db8..96b537c 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -603,7 +603,7 @@ __forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x) __is_nothrow_swappable<__node_allocator>::value) #endif { - __swap_allocator(__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(__alloc(), __x.__alloc(), integral_constant()); using _VSTD::swap; swap(__before_begin()->__next_, __x.__before_begin()->__next_); diff --git a/libcxx/include/list b/libcxx/include/list index 1c085b4..7e4c76d 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -783,7 +783,7 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) "list::swap: Either propagate_on_container_swap must be true" " or the allocators must compare equal"); using _VSTD::swap; - __swap_allocator(__node_alloc(), __c.__node_alloc()); + _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); swap(__sz(), __c.__sz()); swap(__end_, __c.__end_); if (__sz() == 0) diff --git a/libcxx/include/memory b/libcxx/include/memory index eee0bdf..52636e9 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -4890,35 +4890,35 @@ _LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& // --- Helper for container swap -- template -inline _LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc & __a1, _Alloc & __a2) +_LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { - __swap_allocator(__a1, __a2, - integral_constant::propagate_on_container_swap::value>()); + using _VSTD::swap; + swap(__a1, __a2); } template -_LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type) +inline _LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} + +template +inline _LIBCPP_INLINE_VISIBILITY +void __swap_allocator(_Alloc & __a1, _Alloc & __a2) #if _LIBCPP_STD_VER >= 14 _NOEXCEPT #else _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) #endif { - using _VSTD::swap; - swap(__a1, __a2); + _VSTD::__swap_allocator(__a1, __a2, + integral_constant::propagate_on_container_swap::value>()); } -template -inline _LIBCPP_INLINE_VISIBILITY -void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {} - template > struct __noexcept_move_assign_container : public integral_constant::swap(basic_string& __str) __alloc_traits::is_always_equal::value || __alloc() == __str.__alloc(), "swapping non-equal allocators"); _VSTD::swap(__r_.first(), __str.__r_.first()); - __swap_allocator(__alloc(), __str.__alloc()); + _VSTD::__swap_allocator(__alloc(), __str.__alloc()); } // find diff --git a/libcxx/include/vector b/libcxx/include/vector index f4257744..bc83656 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -951,7 +951,7 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__alloc(), this->__begin_, this->__end_, __v.__begin_); + _VSTD::__construct_backward_with_exception_guarantees(this->__alloc(), this->__begin_, this->__end_, __v.__begin_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -966,8 +966,8 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer__alloc(), this->__begin_, __p, __v.__begin_); - __construct_forward_with_exception_guarantees(this->__alloc(), __p, this->__end_, __v.__end_); + _VSTD::__construct_backward_with_exception_guarantees(this->__alloc(), this->__begin_, __p, __v.__begin_); + _VSTD::__construct_forward_with_exception_guarantees(this->__alloc(), __p, this->__end_, __v.__end_); _VSTD::swap(this->__begin_, __v.__begin_); _VSTD::swap(this->__end_, __v.__end_); _VSTD::swap(this->__end_cap(), __v.__end_cap()); @@ -1074,7 +1074,7 @@ typename enable_if vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) { _ConstructTransaction __tx(*this, __n); - __construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_); + _VSTD::__construct_range_forward(this->__alloc(), __first, __last, __tx.__pos_); } // Default constructs __n objects starting at __end_ @@ -2054,7 +2054,7 @@ vector<_Tp, _Allocator>::swap(vector& __x) _VSTD::swap(this->__begin_, __x.__begin_); _VSTD::swap(this->__end_, __x.__end_); _VSTD::swap(this->__end_cap(), __x.__end_cap()); - __swap_allocator(this->__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); #if _LIBCPP_DEBUG_LEVEL == 2 __get_db()->swap(this, &__x); @@ -3232,7 +3232,7 @@ vector::swap(vector& __x) _VSTD::swap(this->__begin_, __x.__begin_); _VSTD::swap(this->__size_, __x.__size_); _VSTD::swap(this->__cap(), __x.__cap()); - __swap_allocator(this->__alloc(), __x.__alloc(), + _VSTD::__swap_allocator(this->__alloc(), __x.__alloc(), integral_constant()); } diff --git a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp new file mode 100644 index 0000000..585ebc0 --- /dev/null +++ b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// + +#include + +#include "test_macros.h" + +struct Incomplete; +template struct Holder { T t; }; + +template> +struct MyAlloc { + using value_type = T; + T *allocate(int n) { return std::allocator().allocate(n); } + void deallocate(T *p, int n) { return std::allocator().deallocate(p, n); } +}; + +int main(int, char**) +{ + std::vector> v; + std::vector> w; + v.push_back(1); + v.insert(v.end(), 2); + v.insert(v.end(), w.begin(), w.end()); + v.pop_back(); + v.erase(v.begin()); + v.erase(v.begin(), v.end()); +#if TEST_STD_VER >= 14 + v.swap(w); +#endif + return 0; +}