From 64626fcaaaa2584a244db423d48e5bebfc6ade33 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 22 Sep 2016 10:56:54 +0100 Subject: [PATCH] Always qualify std::forward in * include/bits/uses_allocator.h (__uses_allocator_construct): Qualify std::forward and ::new. Cast pointer to void*. * include/std/variant (_Variant_storage, _Union, _Variant_base) (__access, __visit_invoke, variant, visit): Qualify std::forward. * testsuite/20_util/variant/compile.cc: Test for ADL problems. From-SVN: r240344 --- libstdc++-v3/ChangeLog | 12 ++++- libstdc++-v3/include/bits/uses_allocator.h | 11 ++-- libstdc++-v3/include/std/variant | 53 ++++++++++--------- .../testsuite/20_util/variant/compile.cc | 47 ++++++++++++++++ 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ff984c37f0e..080b4708894 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,8 +1,16 @@ +2016-09-22 Jonathan Wakely + + * include/bits/uses_allocator.h (__uses_allocator_construct): Qualify + std::forward and ::new. Cast pointer to void*. + * include/std/variant (_Variant_storage, _Union, _Variant_base) + (__access, __visit_invoke, variant, visit): Qualify std::forward. + * testsuite/20_util/variant/compile.cc: Test for ADL problems. + 2016-09-22 Tim Shen - * libstdc++-v3/include/std/variant (variant::operator=): Fix assignment + * include/std/variant (variant::operator=): Fix assignment on references. - * libstdc++-v3/testsuite/20_util/variant/compile.cc: Add test. + * testsuite/20_util/variant/compile.cc: Add test. 2016-09-22 Tim Shen diff --git a/libstdc++-v3/include/bits/uses_allocator.h b/libstdc++-v3/include/bits/uses_allocator.h index 500bd901554..c7d14f33132 100644 --- a/libstdc++-v3/include/bits/uses_allocator.h +++ b/libstdc++-v3/include/bits/uses_allocator.h @@ -144,24 +144,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template void __uses_allocator_construct_impl(__uses_alloc0 __a, _Tp* __ptr, _Args&&... __args) - { new (__ptr) _Tp(forward<_Args>(__args)...); } + { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)...); } template void __uses_allocator_construct_impl(__uses_alloc1<_Alloc> __a, _Tp* __ptr, _Args&&... __args) - { new (__ptr) _Tp(allocator_arg, *__a._M_a, forward<_Args>(__args)...); } + { + ::new ((void*)__ptr) _Tp(allocator_arg, *__a._M_a, + std::forward<_Args>(__args)...); + } template void __uses_allocator_construct_impl(__uses_alloc2<_Alloc> __a, _Tp* __ptr, _Args&&... __args) - { new (__ptr) _Tp(forward<_Args>(__args)..., *__a._M_a); } + { ::new ((void*)__ptr) _Tp(std::forward<_Args>(__args)..., *__a._M_a); } template void __uses_allocator_construct(const _Alloc& __a, _Tp* __ptr, _Args&&... __args) { __uses_allocator_construct_impl(__use_alloc<_Tp, _Alloc, _Args...>(__a), - __ptr, forward<_Args>(__args)...); + __ptr, std::forward<_Args>(__args)...); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 1ad33fc5da0..ac483f3e6ab 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -298,7 +298,7 @@ namespace __variant template constexpr _Variant_storage(in_place_index_t<_Np>, _Args&&... __args) - : _M_union(in_place<_Np>, forward<_Args>(__args)...) + : _M_union(in_place<_Np>, std::forward<_Args>(__args)...) { } ~_Variant_storage() = default; @@ -316,13 +316,13 @@ namespace __variant template constexpr _Union(in_place_index_t<0>, _Args&&... __args) - : _M_first(in_place<0>, forward<_Args>(__args)...) + : _M_first(in_place<0>, std::forward<_Args>(__args)...) { } template> constexpr _Union(in_place_index_t<_Np>, _Args&&... __args) - : _M_rest(in_place<_Np - 1>, forward<_Args>(__args)...) + : _M_rest(in_place<_Np - 1>, std::forward<_Args>(__args)...) { } _Uninitialized<__storage<_First>> _M_first; @@ -386,7 +386,7 @@ namespace __variant template constexpr explicit _Variant_base(in_place_index_t<_Np> __i, _Args&&... __args) - : _Storage(__i, forward<_Args>(__args)...), _M_index(_Np) + : _Storage(__i, std::forward<_Args>(__args)...), _M_index(_Np) { } template @@ -426,7 +426,7 @@ namespace __variant using _Storage = __storage>>; __uses_allocator_construct(__a, static_cast<_Storage*>(_M_storage()), - forward<_Args>(__args)...); + std::forward<_Args>(__args)...); __glibcxx_assert(_M_index == _Np); } @@ -581,7 +581,7 @@ namespace __variant decltype(auto) __access(_Variant&& __v) { return __get_alternative<__reserved_type_map<_Variant&&, __storage<_Tp>>>( - __get_storage(forward<_Variant>(__v))); + __get_storage(std::forward<_Variant>(__v))); } // A helper used to create variadic number of _To types. @@ -591,10 +591,11 @@ namespace __variant // Call the actual visitor. // _Args are qualified storage types. template - decltype(auto) __visit_invoke(_Visitor&& __visitor, - _To_type<_Args, void*>... __ptrs) + decltype(auto) + __visit_invoke(_Visitor&& __visitor, _To_type<_Args, void*>... __ptrs) { - return forward<_Visitor>(__visitor)(__get_alternative<_Args>(__ptrs)...); + return std::forward<_Visitor>(__visitor)( + __get_alternative<_Args>(__ptrs)...); } // Used for storing multi-dimensional vtable. @@ -1010,7 +1011,7 @@ namespace __variant constexpr variant(_Tp&& __t) noexcept(is_nothrow_constructible_v<__accepted_type<_Tp&&>, _Tp&&>) - : variant(in_place<__accepted_index<_Tp&&>>, forward<_Tp>(__t)) + : variant(in_place<__accepted_index<_Tp&&>>, std::forward<_Tp>(__t)) { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); } template>> constexpr explicit variant(in_place_type_t<_Tp>, _Args&&... __args) - : variant(in_place<__index_of<_Tp>>, forward<_Args>(__args)...) + : variant(in_place<__index_of<_Tp>>, std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, initializer_list<_Up> __il, _Args&&... __args) : variant(in_place<__index_of<_Tp>>, __il, - forward<_Args>(__args)...) + std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, _Args&&...>>> constexpr explicit variant(in_place_index_t<_Np>, _Args&&... __args) - : _Base(in_place<_Np>, forward<_Args>(__args)...), + : _Base(in_place<_Np>, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } @@ -1047,7 +1048,7 @@ namespace __variant constexpr explicit variant(in_place_index_t<_Np>, initializer_list<_Up> __il, _Args&&... __args) - : _Base(in_place<_Np>, __il, forward<_Args>(__args)...), + : _Base(in_place<_Np>, __il, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } @@ -1084,7 +1085,7 @@ namespace __variant && !is_same_v, variant>, variant&>> variant(allocator_arg_t, const _Alloc& __a, _Tp&& __t) : variant(allocator_arg, __a, in_place<__accepted_index<_Tp&&>>, - forward<_Tp>(__t)) + std::forward<_Tp>(__t)) { __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); } template, _Args&&... __args) : variant(allocator_arg, __a, in_place<__index_of<_Tp>>, - forward<_Args>(__args)...) + std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, initializer_list<_Up> __il, _Args&&... __args) : variant(allocator_arg, __a, in_place<__index_of<_Tp>>, __il, - forward<_Args>(__args)...) + std::forward<_Args>(__args)...) { __glibcxx_assert(holds_alternative<_Tp>(*this)); } template, _Alloc, _Args&&...>>> variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>, _Args&&... __args) - : _Base(__a, in_place<_Np>, forward<_Args>(__args)...), + : _Base(__a, in_place<_Np>, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } @@ -1125,7 +1126,7 @@ namespace __variant __to_type<_Np>, _Alloc, initializer_list<_Up>&, _Args&&...>>> variant(allocator_arg_t, const _Alloc& __a, in_place_index_t<_Np>, initializer_list<_Up> __il, _Args&&... __args) - : _Base(__a, in_place<_Np>, __il, forward<_Args>(__args)...), + : _Base(__a, in_place<_Np>, __il, std::forward<_Args>(__args)...), _Default_ctor_enabler(_Enable_default_constructor_tag{}) { __glibcxx_assert(index() == _Np); } @@ -1149,7 +1150,7 @@ namespace __variant if (index() == __index) std::get<__index>(*this) = std::forward<_Tp>(__rhs); else - this->emplace<__index>(forward<_Tp>(__rhs)); + this->emplace<__index>(std::forward<_Tp>(__rhs)); __glibcxx_assert(holds_alternative<__accepted_type<_Tp&&>>(*this)); return *this; } @@ -1159,7 +1160,7 @@ namespace __variant { static_assert(__exactly_once<_Tp>, "T should occur for exactly once in alternatives"); - this->emplace<__index_of<_Tp>>(forward<_Args>(__args)...); + this->emplace<__index_of<_Tp>>(std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); } @@ -1168,7 +1169,7 @@ namespace __variant { static_assert(__exactly_once<_Tp>, "T should occur for exactly once in alternatives"); - this->emplace<__index_of<_Tp>>(__il, forward<_Args>(__args)...); + this->emplace<__index_of<_Tp>>(__il, std::forward<_Args>(__args)...); __glibcxx_assert(holds_alternative<_Tp>(*this)); } @@ -1181,7 +1182,7 @@ namespace __variant __try { ::new (this) variant(in_place<_Np>, - forward<_Args>(__args)...); + std::forward<_Args>(__args)...); } __catch (...) { @@ -1200,7 +1201,7 @@ namespace __variant __try { ::new (this) variant(in_place<_Np>, __il, - forward<_Args>(__args)...); + std::forward<_Args>(__args)...); } __catch (...) { @@ -1310,12 +1311,12 @@ namespace __variant visit(_Visitor&& __visitor, _Variants&&... __variants) { using _Result_type = - decltype(forward<_Visitor>(__visitor)(get<0>(__variants)...)); + decltype(std::forward<_Visitor>(__visitor)(get<0>(__variants)...)); static constexpr auto _S_vtable = __detail::__variant::__gen_vtable< _Result_type, _Visitor&&, _Variants&&...>::_S_apply(); auto __func_ptr = _S_vtable._M_access(__variants.index()...); - return (*__func_ptr)(forward<_Visitor>(__visitor), + return (*__func_ptr)(std::forward<_Visitor>(__visitor), __detail::__variant::__get_storage(__variants)...); } diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc index a0a8d70ce87..85a697f5e29 100644 --- a/libstdc++-v3/testsuite/20_util/variant/compile.cc +++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc @@ -418,3 +418,50 @@ void test_pr77641() constexpr std::variant v1 = X{}; } + +namespace adl_trap +{ + struct X { + X() = default; + X(int) { } + X(std::initializer_list, const X&) { } + }; + template void move(T&) { } + template void forward(T&) { } + + struct Visitor { + template void operator()(T&&) { } + }; +} + +void test_adl() +{ + using adl_trap::X; + using std::allocator_arg; + X x; + std::allocator a; + std::initializer_list il; + adl_trap::Visitor vis; + + std::variant v0(x); + v0 = x; + v0.emplace<0>(x); + v0.emplace<0>(il, x); + visit(vis, v0); + variant v1{in_place<0>, x}; + variant v2{in_place, x}; + variant v3{in_place<0>, il, x}; + variant v4{in_place, il, x}; + variant v5{allocator_arg, a, in_place<0>, x}; + variant v6{allocator_arg, a, in_place, x}; + variant v7{allocator_arg, a, in_place<0>, il, x}; + variant v8{allocator_arg, a, in_place, il, x}; + variant v9{allocator_arg, a, in_place, 1}; + + std::variant vr0(x); + vr0 = x; + variant vr1{in_place<0>, x}; + variant vr2{in_place, x}; + variant vr3{allocator_arg, a, in_place<0>, x}; + variant vr4{allocator_arg, a, in_place, x}; +} -- 2.30.2