Hello gcc-team! According to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf [24.3.2.6.4] or http://en.cppreference.com/w/cpp/string/basic_string/insert [9] ``` iterator insert(const_iterator p, initializer_list<charT> il ``` should return an iterator, but the following code ``` #include <string> int main() { std::string s = " world!"; auto it = s.insert(s.begin(), {'h', 'e', 'l', 'l', 'o'}); return 0; } ``` fails with ``` string.cpp: In function ‘int main()’: string.cpp:5:8: error: ‘void it’ has incomplete type auto it = s.insert(s.begin(), {'h', 'e', 'l', 'l', 'o'}); ^~ ``` This behaviour is since g++-4.9
Sounds like this could fix it but I haven't even tried to compile it: --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -1586,13 +1586,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 * @brief Insert an initializer_list of characters. * @param __p Iterator referencing location in string to insert at. * @param __l The initializer_list of characters to insert. + * @return Iterator referencing the first inserted char. * @throw std::length_error If new length exceeds @c max_size(). */ - void + iterator insert(iterator __p, initializer_list<_CharT> __l) { _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); - this->insert(__p - begin(), __l.begin(), __l.size()); + const size_type __pos = __p - begin(); + this->insert(__pos, __l.begin(), __l.size()); + return iterator(this->_M_data() + __pos); } #endif // C++11
I guess include/debug/string should be adjusted too.
Fixing it is an ABI change, so it's not that simple. It should also have a const_iterator parameter, not iterator, and needs to be fixed for both std::string implementations.
GCC 8.1 has been released.
Author: redi Date: Thu Jun 21 22:01:25 2018 New Revision: 261866 URL: https://gcc.gnu.org/viewcvs?rev=261866&root=gcc&view=rev Log: 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<C>)): Add. [_GLIBCXX_USE_CXX11_ABI && !_GLIBCXX_DEFINING_STRING_INSTANTIATIONS] (basic_string::insert(iterator, initializer_list<C>)): 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<C>)): 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. Added: trunk/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/char/83328.cc trunk/libstdc++-v3/testsuite/21_strings/basic_string/modifiers/insert/wchar_t/83328.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/acinclude.m4 trunk/libstdc++-v3/config/abi/pre/gnu.ver trunk/libstdc++-v3/configure trunk/libstdc++-v3/include/bits/basic_string.h trunk/libstdc++-v3/include/debug/string trunk/libstdc++-v3/src/c++11/string-inst.cc trunk/libstdc++-v3/testsuite/util/testsuite_abi.cc
Fixed on trunk so far. I'm going to backport this fix to the gcc-8-branch too.
GCC 8.2 has been released.
This isn't going to be backported, because of the new symbols. So fixed for GCC 9 only.