From cda121ac7a50e53faa61f282f6ef21b58fe8e7fd Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 21 Jun 2018 23:01:25 +0100 Subject: [PATCH] PR libstdc++/83328 add correct basic_string::insert for initializer_list The SSO basic_string has a non-standard insert(iterator, initializer_list) overload, from a C++0x draft. This adds the correct overload, while also preserving the old one so that the old symbol is still exported from the library. The COW basic_string doesn't have any of the C++11 changes to the insert overloads (they all still have non-const iterator parameters and the ones that should return an iterator still return void). This doesn't make any change to the COW string. PR libstdc++/83328 * acinclude.m4 (libtool_VERSION): Bump to 6:26:0. * config/abi/pre/gnu.ver: Add GLIBCXX_3.4.26 and export new symbol. * configure: Regenerate. * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] (basic_string::insert(const_iterator, initializer_list)): Add. [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_STRING_INSTANTIATIONS] (basic_string::insert(iterator, initializer_list)): Suppress definition. * include/debug/string (basic_string::insert(iterator, C)): Change first parameter to const_iterator. (basic_string::insert(iterator, size_type, C)): Likewise. Change return type to iterator. (basic_string::insert(iterator, InputIterator, InputIterator)): Likewise. (basic_string::insert(iterator, initializer_list)): Change first parameter to const_iterator and return type to iterator. * src/c++11/string-inst.cc: Extend comment. * testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc: New. * testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc: New. * testsuite/util/testsuite_abi.cc: Add new symbol version. From-SVN: r261866 --- libstdc++-v3/ChangeLog | 24 ++++++++++ libstdc++-v3/acinclude.m4 | 2 +- libstdc++-v3/config/abi/pre/gnu.ver | 36 +++++++++++++- libstdc++-v3/configure | 2 +- libstdc++-v3/include/bits/basic_string.h | 7 +++ libstdc++-v3/include/debug/string | 29 +++++++----- libstdc++-v3/src/c++11/string-inst.cc | 2 + .../modifiers/insert/char/83328.cc | 46 ++++++++++++++++++ .../modifiers/insert/wchar_t/83328.cc | 47 +++++++++++++++++++ libstdc++-v3/testsuite/util/testsuite_abi.cc | 3 +- 10 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8ad95bb8f3c..d4f27cd09b6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,29 @@ 2018-06-21 Jonathan Wakely + PR libstdc++/83328 + * acinclude.m4 (libtool_VERSION): Bump to 6:26:0. + * config/abi/pre/gnu.ver: Add GLIBCXX_3.4.26 and export new symbol. + * configure: Regenerate. + * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI] + (basic_string::insert(const_iterator, initializer_list)): Add. + [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_STRING_INSTANTIATIONS] + (basic_string::insert(iterator, initializer_list)): Suppress + definition. + * include/debug/string (basic_string::insert(iterator, C)): Change + first parameter to const_iterator. + (basic_string::insert(iterator, size_type, C)): Likewise. Change + return type to iterator. + (basic_string::insert(iterator, InputIterator, InputIterator)): + Likewise. + (basic_string::insert(iterator, initializer_list)): Change first + parameter to const_iterator and return type to iterator. + * src/c++11/string-inst.cc: Extend comment. + * testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc: + New. + * testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc: + New. + * testsuite/util/testsuite_abi.cc: Add new symbol version. + * config/abi/post/x86_64-linux-gnu/baseline_symbols.txt: Update. PR libstdc++/70940 diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 6c855b6c7e5..cf5add167e6 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3749,7 +3749,7 @@ changequote([,])dnl fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:25:0 +libtool_VERSION=6:26:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 5e66dc5cc3f..b59b9a0ff1f 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1703,7 +1703,34 @@ GLIBCXX_3.4.21 { _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE13*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE14_M_replace_aux*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[5-9]*; - _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[2-9]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE2at*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE3end*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE4back*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE4nposE; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE4rend*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE4swap*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE5begin*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE5clear*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE5erase*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE5front*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6append*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6assign*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertI*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEmPK[cw]; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEmPK[cw]m; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEmRKS4_; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEmRKS4_mm; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEmm[cw]; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIP[cw]*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIPK[cw]S4_EE[cw]; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIPK[cw]S4_EEm[cw]; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6rbegin*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6resize*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE7replace*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE7reserve*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE8pop_back*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE9push_back*; + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[7-9]_[MS]_*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EPK*; _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS[34]_; @@ -1982,6 +2009,13 @@ GLIBCXX_3.4.25 { } GLIBCXX_3.4.24; +GLIBCXX_3.4.26 { + + # std::basic_string::insert(const_iterator, initializer_list) + _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIPK[cw]S4_EESt16initializer_listI[cw]E; + +} GLIBCXX_3.4.25; + # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 5a017beaabe..d126addd40a 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -79187,7 +79187,7 @@ $as_echo "$as_me: WARNING: === Symbol versioning will be disabled." >&2;} fi # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:25:0 +libtool_VERSION=6:26:0 # Everything parsed; figure out what files and settings to use. case $enable_symvers in diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 2e6e1c6e5da..a77074da249 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1598,12 +1598,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @param __l The initializer_list of characters to insert. * @throw std::length_error If new length exceeds @c max_size(). */ + iterator + insert(const_iterator __p, initializer_list<_CharT> __l) + { return this->insert(__p, __l.begin(), __l.end()); } + +#ifdef _GLIBCXX_DEFINING_STRING_INSTANTIATIONS + // See PR libstdc++/83328 void insert(iterator __p, initializer_list<_CharT> __l) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); this->insert(__p - begin(), __l.begin(), __l.size()); } +#endif #endif // C++11 /** diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string index 0aa5e9cf825..aa611b2d4a9 100644 --- a/libstdc++-v3/include/debug/string +++ b/libstdc++-v3/include/debug/string @@ -544,7 +544,7 @@ template, } iterator - insert(iterator __p, _CharT __c) + insert(const_iterator __p, _CharT __c) { __glibcxx_check_insert(__p); typename _Base::iterator __res = _Base::insert(__p.base(), __c); @@ -552,37 +552,40 @@ template, return iterator(__res, this); } - void - insert(iterator __p, size_type __n, _CharT __c) + iterator + insert(const_iterator __p, size_type __n, _CharT __c) { __glibcxx_check_insert(__p); - _Base::insert(__p.base(), __n, __c); + typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c); this->_M_invalidate_all(); + return iterator(__res, this); } template - void - insert(iterator __p, _InputIterator __first, _InputIterator __last) + iterator + insert(const_iterator __p, _InputIterator __first, _InputIterator __last) { typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; __glibcxx_check_insert_range2(__p, __first, __last, __dist); + typename _Base::iterator __res; if (__dist.second >= __dp_sign) - _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), - __gnu_debug::__unsafe(__last)); + __res = _Base::insert(__p.base(), __gnu_debug::__unsafe(__first), + __gnu_debug::__unsafe(__last)); else - _Base::insert(__p.base(), __first, __last); - + __res = _Base::insert(__p.base(), __first, __last); this->_M_invalidate_all(); + return iterator(__res, this); } #if __cplusplus >= 201103L - void - insert(iterator __p, std::initializer_list<_CharT> __l) + iterator + insert(const_iterator __p, std::initializer_list<_CharT> __l) { __glibcxx_check_insert(__p); - _Base::insert(__p.base(), __l); + const auto __res = _Base::insert(__p.base(), __l); this->_M_invalidate_all(); + return iterator(__res, this); } #endif // C++11 diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index 47a1c9af3ab..1ea2f2f548f 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -39,6 +39,8 @@ // basic_string(size_type, _CharT, const _Alloc&) constructors from being // replaced by constrained function templates, so that we instantiate the // pre-C++17 definitions. +// This also causes the instantiation of the non-standard C++0x-era +// insert(iterator, initializer_list) overload, see PR libstdc++/83328 #define _GLIBCXX_DEFINING_STRING_INSTANTIATIONS 1 #include diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc new file mode 100644 index 00000000000..0480ce74531 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc @@ -0,0 +1,46 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } +// { dg-require-effective-target cxx11-abi } + +// PR libstdc++/83328 + +#include +#include + +void +test01() +{ + std::string s = "insert"; + auto iter = s.insert(s.cbegin() + 2, std::initializer_list{}); + VERIFY( iter == s.begin() + 2 ); + + iter = s.insert(s.cend(), { 'e', 'd' }); + std::string::iterator* check_type = &iter; + VERIFY( iter == s.cend() - 2 ); + VERIFY( s == "inserted" ); + + iter = s.insert(s.begin() + 6, { ' ', 'r', 'e', 't', 'r', 'i' }); + VERIFY( iter == s.begin() + 6 ); + VERIFY( s == "insert retried" ); +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc new file mode 100644 index 00000000000..af4e29103be --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc @@ -0,0 +1,47 @@ +// Copyright (C) 2018 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } +// { dg-require-effective-target cxx11-abi } + +// PR libstdc++/83328 + +#include +#include + +void +test01() +{ + std::wstring s = L"insert"; + auto iter = s.insert(s.cbegin() + 2, std::initializer_list{}); + VERIFY( iter == s.begin() + 2 ); + + iter = s.insert(s.cend(), { L'e', L'd' }); + std::wstring::iterator* check_type = &iter; + VERIFY( iter == s.cend() - 2 ); + VERIFY( s == L"inserted" ); + + iter = s.insert(s.begin() + 6, { L' ', L'r', L'e', L't', L'r', L'i' }); + VERIFY( iter == s.begin() + 6 ); + VERIFY( s == L"insert retried" ); + +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 1dd69e96a5d..c9aaf74133f 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -206,6 +206,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.23"); known_versions.push_back("GLIBCXX_3.4.24"); known_versions.push_back("GLIBCXX_3.4.25"); + known_versions.push_back("GLIBCXX_3.4.26"); known_versions.push_back("CXXABI_1.3"); known_versions.push_back("CXXABI_LDBL_1.3"); known_versions.push_back("CXXABI_1.3.1"); @@ -236,7 +237,7 @@ check_version(symbol& test, bool added) test.version_status = symbol::incompatible; // Check that added symbols are added in the latest pre-release version. - bool latestp = (test.version_name == "GLIBCXX_3.4.25" + bool latestp = (test.version_name == "GLIBCXX_3.4.26" || test.version_name == "CXXABI_1.3.11" || test.version_name == "CXXABI_FLOAT128" || test.version_name == "CXXABI_TM_1"); -- 2.30.2