[PATCH] PR libstdc++/83328 add correct basic_string::insert for initializer_list

Jonathan Wakely jwakely@redhat.com
Thu Jun 21 22:01:00 GMT 2018


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.

Tested x86_64-linux, committed to trunk.


-------------- next part --------------
commit 2e78faf91176299db541340d24ca3fae71ecf1cf
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Dec 14 11:29:23 2017 +0000

    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.

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/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<typename _CharT, typename _Traits = std::char_traits<_CharT>,
     }
 
     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<typename _CharT, typename _Traits = std::char_traits<_CharT>,
       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<typename _InputIterator>
-      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<C>) overload, see PR libstdc++/83328
 #define _GLIBCXX_DEFINING_STRING_INSTANTIATIONS 1
 
 #include <string>
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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target cxx11-abi }
+
+// PR libstdc++/83328
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  std::string s = "insert";
+  auto iter = s.insert(s.cbegin() + 2, std::initializer_list<char>{});
+  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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target cxx11-abi }
+
+// PR libstdc++/83328
+
+#include <string>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  std::wstring s = L"insert";
+  auto iter = s.insert(s.cbegin() + 2, std::initializer_list<wchar_t>{});
+  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");


More information about the Gcc-patches mailing list