aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2024-10-18 12:11:10 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2024-10-22 17:08:32 +0100
commit85e5b80ee2de80024b736e864e50df136d801402 (patch)
tree0ef0cc9afcfe6e690a5ad044fada5dcc89b3faf1 /libstdc++-v3/testsuite
parentbf11ecbb02b517dff0034f02adacf9269a11a095 (diff)
downloadgcc-85e5b80ee2de80024b736e864e50df136d801402.zip
gcc-85e5b80ee2de80024b736e864e50df136d801402.tar.gz
gcc-85e5b80ee2de80024b736e864e50df136d801402.tar.bz2
libstdc++: Avoid using std::__to_address with iterators
In r12-3935-g82626be2d633a9 I added the partial specialization std::pointer_traits<__normal_iterator<It, Cont>> so that __to_address would work with __normal_iterator objects. Soon after that, François replaced it in r12-6004-g807ad4bc854cae with an overload of __to_address that served the same purpose, but was less complicated and less wrong. I now think that both commits were mistakes, and that instead of adding hacks to make __normal_iterator work with __to_address, we should not be using __to_address with iterators at all before C++20. The pre-C++20 std::__to_address function should only be used with pointer-like types, specifically allocator_traits<A>::pointer types. Those pointer-like types are guaranteed to be contiguous iterators, so that getting a raw memory address from them is OK. For arbitrary iterators, even random access iterators, we don't know that it's safe to lower the iterator to a pointer e.g. for std::deque iterators it's not, because (it + n) == (std::to_address(it) + n) only holds within the same block of the deque's storage. For C++20, std::to_address does work correctly for contiguous iterators, including __normal_iterator, and __to_address just calls std::to_address so also works. But we have to be sure we have an iterator that satisfies the std::contiguous_iterator concept for it to be safe, and we can't check that before C++20. So for pre-C++20 code the correct way to handle iterators that might be pointers or might be __normal_iterator is to call __niter_base, and if necessary use is_pointer to check whether __niter_base returned a real pointer. We currently have some uses of std::__to_address with iterators where we've checked that they're either pointers, or __normal_iterator wrappers around pointers, or satisfy std::contiguous_iterator. But this seems a little fragile, and it would be better to just use std::__niter_base for the pointers and __normal_iterator cases, and use C++20 std::to_address when the C++20 std::contiguous_iterator concept is satisfied. This patch does that. libstdc++-v3/ChangeLog: * include/bits/basic_string.h (basic_string::assign): Replace use of __to_address with __niter_base or std::to_address as appropriate. * include/bits/ptr_traits.h (__to_address): Add comment. * include/bits/shared_ptr_base.h (__shared_ptr): Qualify calls to __to_address. * include/bits/stl_algo.h (find): Replace use of __to_address with __niter_base or std::to_address as appropriate. Only use either of them when the range is not empty. * include/bits/stl_iterator.h (__to_address): Remove overload for __normal_iterator. * include/debug/safe_iterator.h (__to_address): Remove overload for _Safe_iterator. * include/std/ranges (views::counted): Replace use of __to_address with std::to_address. * testsuite/24_iterators/normal_iterator/to_address.cc: Removed.
Diffstat (limited to 'libstdc++-v3/testsuite')
-rw-r--r--libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc19
1 files changed, 0 insertions, 19 deletions
diff --git a/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc b/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc
deleted file mode 100644
index 6afc654..0000000
--- a/libstdc++-v3/testsuite/24_iterators/normal_iterator/to_address.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// { dg-do compile { target { c++11 } } }
-#include <string>
-#include <vector>
-#include <memory>
-
-#include <testsuite_allocator.h>
-
-char* p __attribute__((unused))
- = std::__to_address(std::string("1").begin());
-const char* q __attribute__((unused))
- = std::__to_address(std::string("2").cbegin());
-int* r __attribute__((unused))
- = std::__to_address(std::vector<int>(1, 1).begin());
-const int* s __attribute__((unused))
- = std::__to_address(std::vector<int>(1, 1).cbegin());
-int* t __attribute__((unused))
- = std::__to_address(std::vector<int, __gnu_test::CustomPointerAlloc<int>>(1, 1).begin());
-const int* u __attribute__((unused))
- = std::__to_address(std::vector<int, __gnu_test::CustomPointerAlloc<int>>(1, 1).cbegin());