On 22/06/2015 17:10, Jonathan Wakely wrote: > On 20/06/15 12:59 +0100, Jonathan Wakely wrote: >> On 20/06/15 12:03 +0200, François Dumont wrote: >>> Hi >>> >>> 2 experimental tests are failing in debug mode because >>> __do_str_codecvt is sometimes taking address of string front() and >>> back() even if empty. It wasn't use so not a big issue but it still >>> seems better to avoid. I propose to rather use string begin() to get >>> buffer address. >> >> But derefencing begin() is still undefined for an empty string. >> Shouldn't that fail for debug mode too? It would if we were using basic_string debug implementation but we aren't. We are just using normal implementation with some debug checks which is not enough to detect invalid deference operations. >> Why change one form of >> undefined behaviour that we diagnose to another form that we don't >> diagnose? >> >> It would be better if that function didn't do any work when the input >> range is empty: >> >> --- a/libstdc++-v3/include/bits/locale_conv.h >> +++ b/libstdc++-v3/include/bits/locale_conv.h >> @@ -58,6 +58,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> _OutStr& __outstr, const _Codecvt& __cvt, _State& >> __state, >> size_t& __count, _Fn __fn) >> { >> + if (__first == __last) >> + { >> + __outstr.clear(); >> + return true; >> + } >> + >> size_t __outchars = 0; >> auto __next = __first; >> const auto __maxlen = __cvt.max_length() + 1; > > This makes that change, and also moves wstring_convert into the > ABI-tagged __cxx11 namespace, and fixes a copy&paste error in the > exception thrown from wbuffer_convert. > > Tested powerpc64le-linux, committed to trunk. > > François, your changes to add extra checks in std::string are still > useful separately. > I just applied attached patch then.
François
Index: include/bits/basic_string.h =================================================================== --- include/bits/basic_string.h (revision 224914) +++ include/bits/basic_string.h (working copy) @@ -39,6 +39,7 @@ #include <ext/atomicity.h> #include <ext/alloc_traits.h> #include <debug/debug.h> + #if __cplusplus >= 201103L #include <initializer_list> #endif @@ -903,7 +904,10 @@ */ reference front() noexcept - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read-only (constant) reference to the data at the first @@ -911,7 +915,10 @@ */ const_reference front() const noexcept - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read/write reference to the data at the last @@ -919,7 +926,10 @@ */ reference back() noexcept - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } /** * Returns a read-only (constant) reference to the data at the @@ -927,7 +937,10 @@ */ const_reference back() const noexcept - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } #endif // Modifiers: @@ -1506,7 +1519,10 @@ */ void pop_back() noexcept - { _M_erase(size()-1, 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + _M_erase(size() - 1, 1); + } #endif // C++11 /** @@ -3308,7 +3324,10 @@ */ reference front() - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read-only (constant) reference to the data at the first @@ -3316,7 +3335,10 @@ */ const_reference front() const _GLIBCXX_NOEXCEPT - { return operator[](0); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](0); + } /** * Returns a read/write reference to the data at the last @@ -3324,7 +3346,10 @@ */ reference back() - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } /** * Returns a read-only (constant) reference to the data at the @@ -3332,7 +3357,10 @@ */ const_reference back() const _GLIBCXX_NOEXCEPT - { return operator[](this->size() - 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + return operator[](this->size() - 1); + } #endif // Modifiers: @@ -3819,7 +3847,10 @@ */ void pop_back() // FIXME C++11: should be noexcept. - { erase(size()-1, 1); } + { + _GLIBCXX_DEBUG_ASSERT(!empty()); + erase(size() - 1, 1); + } #endif // C++11 /**