diff options
author | Moritz Sichert <sichert@in.tum.de> | 2021-03-23 15:47:37 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2021-03-23 16:34:42 +0000 |
commit | 09f08fef71fb776a1d850a7b854c7ccf8a3d6c11 (patch) | |
tree | f051c588b5bae5a173ee331a864f4fb2dd4ccd67 /libstdc++-v3 | |
parent | 6b1f841ce0ccf30eda7896ba5ab0aa94c72307b2 (diff) | |
download | gcc-09f08fef71fb776a1d850a7b854c7ccf8a3d6c11.zip gcc-09f08fef71fb776a1d850a7b854c7ccf8a3d6c11.tar.gz gcc-09f08fef71fb776a1d850a7b854c7ccf8a3d6c11.tar.bz2 |
libstdc++: Avoid accidental ADL when calling make_reverse_iterator
std::ranges::reverse_view uses make_reverse_iterator in its
implementation as described in [range.reverse.view]. This accidentally
allows ADL as an unqualified name is used in the call. According to
[contents], however, this should be treated as a qualified lookup into
the std namespace.
This leads to errors due to ambiguous name lookups when another
make_reverse_iterator function is found via ADL.
libstdc++-v3/Changelog:
* include/std/ranges (reverse_view::begin, reverse_view::end):
Qualify make_reverse_iterator calls to avoid ADL.
* testsuite/std/ranges/adaptors/reverse.cc: Test that
views::reverse works when make_reverse_iterator is defined
in an associated namespace.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/include/std/ranges | 12 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc | 18 |
2 files changed, 24 insertions, 6 deletions
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 1be74be..adbc6d7 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -2958,29 +2958,29 @@ namespace views { if constexpr (_S_needs_cached_begin) if (_M_cached_begin._M_has_value()) - return make_reverse_iterator(_M_cached_begin._M_get(_M_base)); + return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base)); auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base)); if constexpr (_S_needs_cached_begin) _M_cached_begin._M_set(_M_base, __it); - return make_reverse_iterator(std::move(__it)); + return std::make_reverse_iterator(std::move(__it)); } constexpr auto begin() requires common_range<_Vp> - { return make_reverse_iterator(ranges::end(_M_base)); } + { return std::make_reverse_iterator(ranges::end(_M_base)); } constexpr auto begin() const requires common_range<const _Vp> - { return make_reverse_iterator(ranges::end(_M_base)); } + { return std::make_reverse_iterator(ranges::end(_M_base)); } constexpr reverse_iterator<iterator_t<_Vp>> end() - { return make_reverse_iterator(ranges::begin(_M_base)); } + { return std::make_reverse_iterator(ranges::begin(_M_base)); } constexpr auto end() const requires common_range<const _Vp> - { return make_reverse_iterator(ranges::begin(_M_base)); } + { return std::make_reverse_iterator(ranges::begin(_M_base)); } constexpr auto size() requires sized_range<_Vp> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc index 593b77e..4738657 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/reverse.cc @@ -131,6 +131,23 @@ test05() VERIFY( test_wrapper<int>::increment_count == 5 ); } +namespace test_ns +{ + struct A {}; + template <typename T> + void make_reverse_iterator(T&&) {} +} // namespace test_ns + +void test06() +{ + // Check that views::reverse works and does not use ADL which could lead + // to accidentally finding test_ns::make_reverse_iterator(const A&). + test_ns::A as[] = {{}, {}}; + auto v = as | std::views::reverse; + static_assert(std::ranges::view<decltype(v)>); + static_assert(std::ranges::view<decltype(v)>); +} + int main() { @@ -139,4 +156,5 @@ main() test03(); test04(); test05(); + test06(); } |