From c9dbf0f2a1e937283b0435b76ce41bcb343fffb8 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Sun, 2 Jan 2022 17:25:40 +0100 Subject: [PATCH] [libc++] Fix __wrap_iter copy-assignment in constexpr contexts Fixes https://github.com/llvm/llvm-project/issues/52902 In debug mode during constant evaluation the iterator was never assigend. There seem to be no other instances of this bug. Reviewed By: Quuxplusone, Mordante, #libc, ldionne Spies: ldionne, libcxx-commits Differential Revision: https://reviews.llvm.org/D116346 --- libcxx/include/__iterator/wrap_iter.h | 5 ++-- .../string.iterators/iterators.pass.cpp | 23 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h index cfcc9857b3fc..5a386eec4b22 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -69,9 +69,10 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter& operator=(const __wrap_iter& __x) { - if (this != _VSTD::addressof(__x) && !__libcpp_is_constant_evaluated()) + if (this != _VSTD::addressof(__x)) { - __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); + if (!__libcpp_is_constant_evaluated()) + __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); __i = __x.__i; } return *this; diff --git a/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp index c7c1eb25eeb6..187452b6020e 100644 --- a/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp +++ b/libcxx/test/std/strings/basic.string/string.iterators/iterators.pass.cpp @@ -23,12 +23,13 @@ #include "test_macros.h" template -void test() +TEST_CONSTEXPR_CXX20 void test() { { // N3644 testing typename C::iterator ii1{}, ii2{}; typename C::iterator ii4 = ii1; typename C::const_iterator cii{}; + assert ( ii1 == ii2 ); assert ( ii1 == ii4 ); @@ -49,10 +50,17 @@ void test() assert (cii - ii1 == 0); assert (ii1 - cii == 0); } + { + C a; + typename C::iterator i1 = a.begin(); + typename C::iterator i2; + assert ( i1 != i2 ); + i2 = i1; + assert ( i1 == i2 ); + } } -int main(int, char**) -{ +TEST_CONSTEXPR_CXX20 bool test() { test(); #ifndef TEST_HAS_NO_WIDE_CHARACTERS test(); @@ -65,5 +73,14 @@ int main(int, char**) test(); test(); + return true; +} + +int main(int, char**) +{ + test(); +#if defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L + static_assert(test()); +#endif return 0; }