In Debug Mode, range insert/assign methods of vector, deque and
inplace_vector call __gnu_debug::__unsafe on their iterator arguments
under std::__is_constant_evaluated(). The overload for _Safe_iterator
is not constexpr, so the caller can't pass Debug Mode iterators in a
constant expression.
PR libstdc++/128115
libstdc++-v3/ChangeLog:
* include/debug/safe_iterator.h (__unsafe): Add
_GLIBCXX20_CONSTEXPR to the _Safe_iterator overload.
* testsuite/23_containers/vector/debug/128115-1.cc: New test.
Signed-off-by: Mishmish Dev <[email protected]>
---
Tested on x86_64-pc-linux-gnu: full libstdc++ testsuite with
GLIBCXX_TESTSUITE_STDS=20,23,26, no regressions.
Independent of the other patch in this series.
OK for trunk, and backports up to 14?
libstdc++-v3/include/debug/safe_iterator.h | 1 +
.../23_containers/vector/debug/128115-1.cc | 53 +++++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644
libstdc++-v3/testsuite/23_containers/vector/debug/128115-1.cc
diff --git a/libstdc++-v3/include/debug/safe_iterator.h
b/libstdc++-v3/include/debug/safe_iterator.h
index 8c049961cca..c63faa2a61e 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -1190,6 +1190,7 @@ namespace __gnu_debug
#endif
template<typename _Iterator, typename _Sequence>
+ _GLIBCXX20_CONSTEXPR
inline _Iterator
__unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it)
{ return __it.base(); }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/128115-1.cc
b/libstdc++-v3/testsuite/23_containers/vector/debug/128115-1.cc
new file mode 100644
index 00000000000..75c0b1b5157
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/128115-1.cc
@@ -0,0 +1,53 @@
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-D_GLIBCXX_DEBUG" }
+
+// PR libstdc++/128115
+// Debug Mode range members call __gnu_debug::__unsafe on safe iterators
+// during constant evaluation.
+
+#include <vector>
+#include <deque>
+#include <iterator>
+#if __has_include(<inplace_vector>)
+# include <inplace_vector>
+#endif
+
+constexpr bool
+test_vector()
+{
+ std::vector<int> a{1, 2, 3};
+ std::vector<int> v;
+ v.assign(a.begin(), a.end());
+ v.insert(v.end(), a.begin(), a.end());
+ v.assign(a.rbegin(), a.rend());
+ v.insert(v.begin(), std::make_move_iterator(a.begin()),
+ std::make_move_iterator(a.end()));
+ return v.size() == 6 && v[0] == 1 && v[3] == 3;
+}
+static_assert( test_vector() );
+
+#if __cpp_lib_constexpr_deque >= 202502L
+constexpr bool
+test_deque()
+{
+ std::deque<int> a{1, 2, 3};
+ std::deque<int> d;
+ d.assign(a.begin(), a.end());
+ d.insert(d.end(), a.begin(), a.end());
+ return d.size() == 6 && d[3] == 1;
+}
+static_assert( test_deque() );
+#endif
+
+#ifdef __cpp_lib_inplace_vector
+constexpr bool
+test_inplace_vector()
+{
+ std::inplace_vector<int, 6> a{1, 2, 3};
+ std::inplace_vector<int, 6> v;
+ v.assign(a.begin(), a.end());
+ v.insert(v.end(), a.begin(), a.end());
+ return v.size() == 6 && v[3] == 1;
+}
+static_assert( test_inplace_vector() );
+#endif
--
2.55.0