Patchwork [v3] more abi_tagging for DR130

login
register
mail settings
Submitter Benjamin Kosnik
Date June 10, 2013, 11:23 p.m.
Message ID <20130610162311.42f9d489@oakwood>
Download mbox | patch
Permalink /patch/250419/
State New
Headers show

Comments

Benjamin Kosnik - June 10, 2013, 11:23 p.m.
Some of the DR130-mandated signature changes for C++11 require the use
of abi_tag to properly distinguish from C++98 calls of the same
function, but with a different return type.

I've audited libstdc++ for C++98/C++11 API differences that are
signature changes that mangle the same. C++11 to C++14 changes of this
type will be mangled with abi_tag(cxx14), but I didn't notice any. 

I put in reproducers for the fail, but these are only active on ia32 at
the moment. I've found testing a specific multilib in libstdc++ (ie
-m32 on x76_64) more difficult than imagined, so am just simplifying to
one psABI that demonstrates the issue. No doubt there are others. I'm
not quite sure how to abstract this....

Similar to the complex::real/imag use, there are separate test cases to
confirm the newly mangled versions. I've noticed that these newly
mangled names using abi_tag cannot be presently demangled: see PR57581.

Since this is impacting C++98/C++11 compat, I intend to put this on 4.8
branch after a couple of days mellowing on trunk.

tested x86_64/linux
tested i686/linux

-benjamin

Patch

2013-06-10  Benjamin Kosnik  <bkoz@redhat.com>

	* include/bits/c++config (_GLIBCXX_ABI_TAG_CXX11): Add.
	* include/bits/stl_map.h (erase): Use abi_tag when C++11.
	* include/bits/stl_multimap.h: Same.
	* include/bits/stl_multiset.h: Same.
	* include/bits/stl_set.h: Same.
	* include/bits/stl_tree.h: Same.
	* include/std/complex (real, imag): Use macro for abi_tag.

	* testsuite/lib/libstdc++.exp: Disable inlinling with -fno-inline.
	* testsuite/util/testsuite_containers.h (erase_external): New
	declarations.
	(erase_external_iterators): Same.
	(linkage_check_cxx98_cxx11_erase): Same.
	(linkage_check_cxx98_cxx11_erase_iterators): Same.
	* testsuite/util/testsuite_shared.cc: Define.
	* testsuite/23_containers/map/modifiers/erase/abi_tag.cc: New.
	* testsuite/23_containers/map/modifiers/erase/
	dr130-linkage-check.cc: New.
	* testsuite/23_containers/multimap/modifiers/erase/abi_tag.cc: New.
	* testsuite/23_containers/multimap/modifiers/erase/
	dr130-linkage-check.cc: New.
	* testsuite/23_containers/multiset/modifiers/erase/abi_tag.cc: New.
	* testsuite/23_containers/multiset/modifiers/erase/
	dr130-linkage-check.cc: New.
	* testsuite/23_containers/set/modifiers/erase/abi_tag.cc: New.
	* testsuite/23_containers/set/modifiers/erase/dr130-linkage-check.cc:
	New.
	* testsuite/ext/profile/mutex_extensions_neg.cc: Adjust line number.

	* testsuite/23_containers/map/dr130.cc: Move...
	* testsuite/23_containers/map/modifiers/dr130.cc: ...here.
	* testsuite/23_containers/multimap/dr130.cc: Move ...
	* testsuite/23_containers/multimap/modifiers/dr130.cc: ...here.
	* testsuite/23_containers/multiset/dr130.cc: Move...
	* testsuite/23_containers/multiset/modifiers/dr130.cc: ...here.
	* testsuite/23_containers/set/dr130.cc: Move...
	* testsuite/23_containers/set/modifiers/dr130.cc: ...here.

diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 04ae4cb..aca8484 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -84,6 +84,12 @@ 
 # define _GLIBCXX_DEPRECATED
 #endif
 
+// Macros for ABI tag attributes.
+#ifndef _GLIBCXX_ABI_TAG_CXX11
+# define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11")))
+#endif
+
+
 #if __cplusplus
 
 // Macro for constexpr, to support in mixed 03/0x mode.
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 1f6763c..d05e4b9 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -690,7 +690,8 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       erase(const_iterator __position)
       { return _M_t.erase(__position); }
 
-      // LWG 2059.
+      // LWG 2059
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(iterator __position)
       { return _M_t.erase(__position); }
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 696e298..809ea54 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -596,6 +596,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { return _M_t.erase(__position); }
 
       // LWG 2059.
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(iterator __position)
       { return _M_t.erase(__position); }
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index ea22f4c..8ceb02a 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -532,6 +532,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  not touched in any way.  Managing the pointer is the user's
        *  responsibility.
        */
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __position)
       { return _M_t.erase(__position); }
@@ -583,6 +584,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  touched in any way.  Managing the pointer is the user's
        *  responsibility.
        */
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __first, const_iterator __last)
       { return _M_t.erase(__first, __last); }
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 14f9f5a..44eb589 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -546,6 +546,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  touched in any way.  Managing the pointer is the user's
        *  responsibility.
        */
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __position)
       { return _M_t.erase(__position); }
@@ -597,6 +598,7 @@  _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  the element is itself a pointer, the pointed-to memory is not touched
        *  in any way.  Managing the pointer is the user's responsibility.
        */
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __first, const_iterator __last)
       { return _M_t.erase(__first, __last); }
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index cb5a8ef..91bf4df 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -336,21 +336,21 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
               _Node_allocator;
 
     protected:
-      typedef _Rb_tree_node_base* _Base_ptr;
-      typedef const _Rb_tree_node_base* _Const_Base_ptr;
+      typedef _Rb_tree_node_base* 		_Base_ptr;
+      typedef const _Rb_tree_node_base* 	_Const_Base_ptr;
 
     public:
-      typedef _Key key_type;
-      typedef _Val value_type;
-      typedef value_type* pointer;
-      typedef const value_type* const_pointer;
-      typedef value_type& reference;
-      typedef const value_type& const_reference;
-      typedef _Rb_tree_node<_Val>* _Link_type;
-      typedef const _Rb_tree_node<_Val>* _Const_Link_type;
-      typedef size_t size_type;
-      typedef ptrdiff_t difference_type;
-      typedef _Alloc allocator_type;
+      typedef _Key 				key_type;
+      typedef _Val 				value_type;
+      typedef value_type* 			pointer;
+      typedef const value_type* 		const_pointer;
+      typedef value_type& 			reference;
+      typedef const value_type& 		const_reference;
+      typedef _Rb_tree_node<_Val>* 		_Link_type;
+      typedef const _Rb_tree_node<_Val>*	_Const_Link_type;
+      typedef size_t 				size_type;
+      typedef ptrdiff_t 			difference_type;
+      typedef _Alloc 				allocator_type;
 
       _Node_allocator&
       _M_get_Node_allocator() _GLIBCXX_NOEXCEPT
@@ -800,6 +800,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 130. Associative erase should return an iterator.
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __position)
       {
@@ -810,6 +811,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       // LWG 2059.
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(iterator __position)
       {
@@ -833,6 +835,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 130. Associative erase should return an iterator.
+      _GLIBCXX_ABI_TAG_CXX11
       iterator
       erase(const_iterator __first, const_iterator __last)
       {
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index b31e8b1..7f100a0 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -142,11 +142,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cplusplus >= 201103L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // DR 387. std::complex over-encapsulated.
-      __attribute ((__abi_tag__ ("cxx11")))
+      _GLIBCXX_ABI_TAG_CXX11
       constexpr _Tp 
       real() { return _M_real; }
 
-      __attribute ((__abi_tag__ ("cxx11")))
+      _GLIBCXX_ABI_TAG_CXX11
       constexpr _Tp 
       imag() { return _M_imag; }
 #else
diff --git a/libstdc++-v3/testsuite/23_containers/map/dr130.cc b/libstdc++-v3/testsuite/23_containers/map/dr130.cc
deleted file mode 100644
index e155b4a..0000000
--- a/libstdc++-v3/testsuite/23_containers/map/dr130.cc
+++ /dev/null
@@ -1,77 +0,0 @@ 
-// { dg-options "-std=gnu++0x" }
-// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
-//
-// Copyright (C) 2009-2013 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/>.
-
-#include <map>
-#include <testsuite_hooks.h>
-
-//  DR 130. Associative erase should return an iterator.
-void
-test01()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  map<int, int> m0;
-  typedef map<int, int>::iterator iterator;
-  typedef map<int, int>::const_iterator const_iterator;
-  typedef map<int, int>::value_type value_type;
-  typedef pair<iterator, bool> insert_return_type;
-
-  m0.insert(value_type(1, 1));
-  insert_return_type irt1 = m0.insert(value_type(2, 2));
-  insert_return_type irt2 = m0.insert(value_type(3, 3));
-
-  iterator pos1 = m0.erase(irt1.first);
-  VERIFY( pos1 == irt2.first );
-
-  iterator pos2 = m0.erase(irt2.first);
-  VERIFY( pos2 == m0.end() );
-}
-
-void
-test02()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  map<int, int> m0;
-  typedef map<int, int>::iterator iterator;
-  typedef map<int, int>::const_iterator const_iterator;
-  typedef map<int, int>::value_type value_type;
-  typedef pair<iterator, bool> insert_return_type;
-
-  insert_return_type irt0 = m0.insert(value_type(1, 1));
-  m0.insert(value_type(2, 2));
-  insert_return_type irt2 = m0.insert(value_type(3, 3));
-  insert_return_type irt3 = m0.insert(value_type(4, 4));
-
-  iterator pos1 = m0.erase(irt0.first, irt2.first);
-  VERIFY( pos1 == irt2.first );
-
-  iterator pos2 = m0.erase(irt2.first, ++irt3.first);
-  VERIFY( pos2 == m0.end() );
-}
-
-int
-main()
-{
-  test01();
-  test02();
-}
diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/dr130.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/dr130.cc
new file mode 100644
index 0000000..e155b4a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/dr130.cc
@@ -0,0 +1,77 @@ 
+// { dg-options "-std=gnu++0x" }
+// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
+//
+// Copyright (C) 2009-2013 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/>.
+
+#include <map>
+#include <testsuite_hooks.h>
+
+//  DR 130. Associative erase should return an iterator.
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  map<int, int> m0;
+  typedef map<int, int>::iterator iterator;
+  typedef map<int, int>::const_iterator const_iterator;
+  typedef map<int, int>::value_type value_type;
+  typedef pair<iterator, bool> insert_return_type;
+
+  m0.insert(value_type(1, 1));
+  insert_return_type irt1 = m0.insert(value_type(2, 2));
+  insert_return_type irt2 = m0.insert(value_type(3, 3));
+
+  iterator pos1 = m0.erase(irt1.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = m0.erase(irt2.first);
+  VERIFY( pos2 == m0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  map<int, int> m0;
+  typedef map<int, int>::iterator iterator;
+  typedef map<int, int>::const_iterator const_iterator;
+  typedef map<int, int>::value_type value_type;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = m0.insert(value_type(1, 1));
+  m0.insert(value_type(2, 2));
+  insert_return_type irt2 = m0.insert(value_type(3, 3));
+  insert_return_type irt3 = m0.insert(value_type(4, 4));
+
+  iterator pos1 = m0.erase(irt0.first, irt2.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = m0.erase(irt2.first, ++irt3.first);
+  VERIFY( pos2 == m0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/abi_tag.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/abi_tag.cc
new file mode 100644
index 0000000..0a17c56
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/abi_tag.cc
@@ -0,0 +1,35 @@ 
+// { dg-do compile }
+// { dg-options -std=c++11 }
+
+// Copyright (C) 2013 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+// Test that the C++11 variants have an ABI tag
+
+#include <map>
+
+using container = std::map<int, int>;
+using iterator = typename container::iterator;
+using const_iterator = typename container::const_iterator;
+
+// { dg-final { scan-assembler "_ZNSt3mapIiiSt4lessIiESaISt4pairIKiiEEE5eraseB5cxx11ESt17_Rb_tree_iteratorIS4_E" } }
+iterator (container::*p1)(iterator) = &container::erase;
diff --git a/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/dr130-linkage-check.cc b/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/dr130-linkage-check.cc
new file mode 100644
index 0000000..9d7cde9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/modifiers/erase/dr130-linkage-check.cc
@@ -0,0 +1,40 @@ 
+// { dg-require-effective-target ia32 }
+// { dg-require-sharedlib "" }
+// { dg-options "-fno-inline -std=gnu++11 ./testsuite_shared.so" }
+// 2013-06-03  Benjamin Kosnik  <bkoz@redhat..com>
+//
+// Copyright (C) 2013 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/>.
+
+#include <testsuite_containers.h>
+
+int main()
+{
+  typedef std::map<int, int>		container_type;
+
+  {
+    container_type s { {0,0} , {1,1} , {2,2} };
+    __gnu_test::linkage_check_cxx98_cxx11_erase(s);
+  }
+
+  {
+    container_type s { {0,0} , {1,1} , {2,2} };
+    __gnu_test::linkage_check_cxx98_cxx11_erase_iterators(s);
+  }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/dr130.cc b/libstdc++-v3/testsuite/23_containers/multimap/dr130.cc
deleted file mode 100644
index b303fa6..0000000
--- a/libstdc++-v3/testsuite/23_containers/multimap/dr130.cc
+++ /dev/null
@@ -1,87 +0,0 @@ 
-// { dg-options "-std=gnu++0x" }
-
-// Copyright (C) 2009-2013 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/>.
-
-
-// NOTE: This makes use of the fact that we know how moveable
-// is implemented on multiset (via swap). If the implementation changed
-// this test may begin to fail.
-
-#include <map>
-#include <vector>
-#include <testsuite_hooks.h>
-
-using namespace std;
-
-void
-test01()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  multimap<int, int> mm0;
-  typedef multimap<int, int>::iterator iterator;
-  typedef multimap<int, int>::const_iterator const_iterator;
-  typedef multimap<int, int>::value_type value_type;
-  typedef iterator insert_return_type;
-
-  vector<insert_return_type> irt;
-  for (int i = 1; i <= 4; ++i)
-    for (int j = 1; j <= i; ++j)
-      irt.push_back( mm0.insert( value_type( i, i ) ) );
-
-  iterator pos1 = mm0.erase(irt[1]);
-  VERIFY( pos1 == irt[2] );
-
-  iterator pos2 = mm0.erase(irt[2]);
-  VERIFY( pos2 == irt[3] );
-
-  iterator pos3 = mm0.erase(irt[9]);
-  VERIFY( pos3 == mm0.end() );
-}
-
-void
-test02()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  multimap<int, int> mm0;
-  typedef multimap<int, int>::iterator iterator;
-  typedef multimap<int, int>::const_iterator const_iterator;
-  typedef multimap<int, int>::value_type value_type;
-  typedef iterator insert_return_type;
-
-  vector<insert_return_type> irt;
-  for (int i = 1; i <= 4; ++i)
-    for (int j = 1; j <= i; ++j)
-      irt.push_back( mm0.insert( value_type( i, i ) ) );
-
-  iterator pos1 = mm0.erase(irt[3], irt[6]);
-  VERIFY( pos1 == irt[6] );
-
-  iterator pos2 = mm0.erase(irt[6], ++irt[9]);
-  VERIFY( pos2 == mm0.end() );
-}
-
-int
-main()
-{
-  test01();
-  test02();
-}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/dr130.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/dr130.cc
new file mode 100644
index 0000000..b303fa6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/dr130.cc
@@ -0,0 +1,87 @@ 
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009-2013 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/>.
+
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <map>
+#include <vector>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multimap<int, int> mm0;
+  typedef multimap<int, int>::iterator iterator;
+  typedef multimap<int, int>::const_iterator const_iterator;
+  typedef multimap<int, int>::value_type value_type;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for (int i = 1; i <= 4; ++i)
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( mm0.insert( value_type( i, i ) ) );
+
+  iterator pos1 = mm0.erase(irt[1]);
+  VERIFY( pos1 == irt[2] );
+
+  iterator pos2 = mm0.erase(irt[2]);
+  VERIFY( pos2 == irt[3] );
+
+  iterator pos3 = mm0.erase(irt[9]);
+  VERIFY( pos3 == mm0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multimap<int, int> mm0;
+  typedef multimap<int, int>::iterator iterator;
+  typedef multimap<int, int>::const_iterator const_iterator;
+  typedef multimap<int, int>::value_type value_type;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for (int i = 1; i <= 4; ++i)
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( mm0.insert( value_type( i, i ) ) );
+
+  iterator pos1 = mm0.erase(irt[3], irt[6]);
+  VERIFY( pos1 == irt[6] );
+
+  iterator pos2 = mm0.erase(irt[6], ++irt[9]);
+  VERIFY( pos2 == mm0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/abi_tag.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/abi_tag.cc
new file mode 100644
index 0000000..7bd26a3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/abi_tag.cc
@@ -0,0 +1,35 @@ 
+// { dg-do compile }
+// { dg-options -std=c++11 }
+
+// Copyright (C) 2013 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+// Test that the C++11 variants have an ABI tag
+
+#include <map>
+
+using container = std::multimap<int, int>;
+using iterator = typename container::iterator;
+using const_iterator = typename container::const_iterator;
+
+// { dg-final { scan-assembler "_ZNSt8multimapIiiSt4lessIiESaISt4pairIKiiEEE5eraseB5cxx11ESt17_Rb_tree_iteratorIS4_E" } }
+iterator (container::*p1)(iterator) = &container::erase;
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/dr130-linkage-check.cc b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/dr130-linkage-check.cc
new file mode 100644
index 0000000..236100c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/modifiers/erase/dr130-linkage-check.cc
@@ -0,0 +1,40 @@ 
+// { dg-require-effective-target ia32 }
+// { dg-require-sharedlib "" }
+// { dg-options "-fno-inline -std=gnu++11 ./testsuite_shared.so" }
+// 2013-06-03  Benjamin Kosnik  <bkoz@redhat..com>
+//
+// Copyright (C) 2013 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/>.
+
+#include <testsuite_containers.h>
+
+int main()
+{
+  typedef std::multimap<int, int>		container_type;
+
+  {
+    container_type s { {0,0} , {1,1} , {2,2} };
+    __gnu_test::linkage_check_cxx98_cxx11_erase(s);
+  }
+
+  {
+    container_type s { {0,0} , {1,1} , {2,2} };
+    __gnu_test::linkage_check_cxx98_cxx11_erase_iterators(s);
+  }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/dr130.cc b/libstdc++-v3/testsuite/23_containers/multiset/dr130.cc
deleted file mode 100644
index fc8aaf6..0000000
--- a/libstdc++-v3/testsuite/23_containers/multiset/dr130.cc
+++ /dev/null
@@ -1,85 +0,0 @@ 
-// { dg-options "-std=gnu++0x" }
-
-// Copyright (C) 2009-2013 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/>.
-
-
-// NOTE: This makes use of the fact that we know how moveable
-// is implemented on multiset (via swap). If the implementation changed
-// this test may begin to fail.
-
-#include <set>
-#include <vector>
-#include <testsuite_hooks.h>
-
-using namespace std;
-
-void
-test01()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  multiset<int> ms0;
-  typedef multiset<int>::iterator iterator;
-  typedef multiset<int>::const_iterator const_iterator;
-  typedef iterator insert_return_type;
-
-  vector<insert_return_type> irt;
-  for ( int i = 1; i <= 4; ++i )
-    for (int j = 1; j <= i; ++j)
-      irt.push_back( ms0.insert( i ) );
-
-  iterator pos1 = ms0.erase(irt[1]);
-  VERIFY( pos1 == irt[2] );
-
-  iterator pos2 = ms0.erase(irt[2]);
-  VERIFY( pos2 == irt[3] );
-
-  iterator pos3 = ms0.erase(irt[9]);
-  VERIFY( pos3 == ms0.end() );
-}
-
-void
-test02()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  multiset<int> ms0;
-  typedef multiset<int>::iterator iterator;
-  typedef multiset<int>::const_iterator const_iterator;
-  typedef iterator insert_return_type;
-
-  vector<insert_return_type> irt;
-  for ( int i = 1; i <= 4; ++i )
-    for (int j = 1; j <= i; ++j)
-      irt.push_back( ms0.insert( i ) );
-
-  iterator pos1 = ms0.erase(irt[3], irt[6]);
-  VERIFY( pos1 == irt[6] );
-
-  iterator pos2 = ms0.erase(irt[6], ++irt[9]);
-  VERIFY( pos2 == ms0.end() );
-}
-
-int
-main()
-{
-  test01();
-  test02();
-}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/dr130.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/dr130.cc
new file mode 100644
index 0000000..fc8aaf6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/dr130.cc
@@ -0,0 +1,85 @@ 
+// { dg-options "-std=gnu++0x" }
+
+// Copyright (C) 2009-2013 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/>.
+
+
+// NOTE: This makes use of the fact that we know how moveable
+// is implemented on multiset (via swap). If the implementation changed
+// this test may begin to fail.
+
+#include <set>
+#include <vector>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multiset<int> ms0;
+  typedef multiset<int>::iterator iterator;
+  typedef multiset<int>::const_iterator const_iterator;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for ( int i = 1; i <= 4; ++i )
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( ms0.insert( i ) );
+
+  iterator pos1 = ms0.erase(irt[1]);
+  VERIFY( pos1 == irt[2] );
+
+  iterator pos2 = ms0.erase(irt[2]);
+  VERIFY( pos2 == irt[3] );
+
+  iterator pos3 = ms0.erase(irt[9]);
+  VERIFY( pos3 == ms0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  multiset<int> ms0;
+  typedef multiset<int>::iterator iterator;
+  typedef multiset<int>::const_iterator const_iterator;
+  typedef iterator insert_return_type;
+
+  vector<insert_return_type> irt;
+  for ( int i = 1; i <= 4; ++i )
+    for (int j = 1; j <= i; ++j)
+      irt.push_back( ms0.insert( i ) );
+
+  iterator pos1 = ms0.erase(irt[3], irt[6]);
+  VERIFY( pos1 == irt[6] );
+
+  iterator pos2 = ms0.erase(irt[6], ++irt[9]);
+  VERIFY( pos2 == ms0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/abi_tag.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/abi_tag.cc
new file mode 100644
index 0000000..bbe2d05
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/abi_tag.cc
@@ -0,0 +1,38 @@ 
+// { dg-do compile }
+// { dg-options -std=c++11 }
+
+// Copyright (C) 2013 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+// Test that the C++11 variants have an ABI tag
+
+#include <set>
+
+using container = std::multiset<int>;
+using iterator = typename container::iterator;
+using const_iterator = typename container::const_iterator;
+
+// { dg-final { scan-assembler "_ZNSt8multisetIiSt4lessIiESaIiEE5eraseB5cxx11ESt23_Rb_tree_const_iteratorIiE" } }
+iterator (container::*p1)(const_iterator) = &container::erase;
+
+// { dg-final { scan-assembler "_ZNSt8multisetIiSt4lessIiESaIiEE5eraseB5cxx11ESt23_Rb_tree_const_iteratorIiES5_" } }
+iterator (container::*p2)(const_iterator, const_iterator) = &container::erase;
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/dr130-linkage-check.cc b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/dr130-linkage-check.cc
new file mode 100644
index 0000000..9155b64
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/modifiers/erase/dr130-linkage-check.cc
@@ -0,0 +1,40 @@ 
+// { dg-require-effective-target ia32 }
+// { dg-require-sharedlib "" }
+// { dg-options "-fno-inline -std=gnu++11 ./testsuite_shared.so" }
+// 2013-06-03  Benjamin Kosnik  <bkoz@redhat..com>
+//
+// Copyright (C) 2013 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/>.
+
+#include <testsuite_containers.h>
+
+int main()
+{
+  typedef std::multiset<int>			container_type;
+
+  {
+    container_type s { 0, 1, 2 };
+    __gnu_test::linkage_check_cxx98_cxx11_erase(s);
+  }
+
+  {
+    container_type s { 0, 1, 2 };
+    __gnu_test::linkage_check_cxx98_cxx11_erase_iterators(s);
+  }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/dr130.cc b/libstdc++-v3/testsuite/23_containers/set/dr130.cc
deleted file mode 100644
index 18b8632..0000000
--- a/libstdc++-v3/testsuite/23_containers/set/dr130.cc
+++ /dev/null
@@ -1,75 +0,0 @@ 
-// { dg-options "-std=gnu++0x" }
-// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
-//
-// Copyright (C) 2009-2013 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/>.
-
-#include <set>
-#include <testsuite_hooks.h>
-
-//  DR 130. Associative erase should return an iterator.
-void
-test01()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  set<int> s0;
-  typedef set<int>::iterator iterator;
-  typedef set<int>::const_iterator const_iterator;
-  typedef pair<iterator, bool> insert_return_type;
-
-  s0.insert(1);
-  insert_return_type irt1 = s0.insert(2);
-  insert_return_type irt2 = s0.insert(3);
-
-  iterator pos1 = s0.erase(irt1.first);
-  VERIFY( pos1 == irt2.first );
-
-  iterator pos2 = s0.erase(irt2.first);
-  VERIFY( pos2 == s0.end() );
-}
-
-void
-test02()
-{
-  bool test __attribute__((unused)) = true;
-  using namespace std;
-
-  set<int> s0;
-  typedef set<int>::iterator iterator;
-  typedef set<int>::const_iterator const_iterator;
-  typedef pair<iterator, bool> insert_return_type;
-
-  insert_return_type irt0 = s0.insert(1);
-  s0.insert(2);
-  insert_return_type irt2 = s0.insert(3);
-  insert_return_type irt3 = s0.insert(4);
-
-  iterator pos1 = s0.erase(irt0.first, irt2.first);
-  VERIFY( pos1 == irt2.first );
-
-  iterator pos2 = s0.erase(irt2.first, ++irt3.first);
-  VERIFY( pos2 == s0.end() );
-}
-
-int
-main()
-{
-  test01();
-  test02();
-}
diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/dr130.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/dr130.cc
new file mode 100644
index 0000000..18b8632
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/dr130.cc
@@ -0,0 +1,75 @@ 
+// { dg-options "-std=gnu++0x" }
+// 2008-07-22  Edward Smith-Rowland  <3dw4rd@verizon.net>
+//
+// Copyright (C) 2009-2013 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/>.
+
+#include <set>
+#include <testsuite_hooks.h>
+
+//  DR 130. Associative erase should return an iterator.
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  set<int> s0;
+  typedef set<int>::iterator iterator;
+  typedef set<int>::const_iterator const_iterator;
+  typedef pair<iterator, bool> insert_return_type;
+
+  s0.insert(1);
+  insert_return_type irt1 = s0.insert(2);
+  insert_return_type irt2 = s0.insert(3);
+
+  iterator pos1 = s0.erase(irt1.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = s0.erase(irt2.first);
+  VERIFY( pos2 == s0.end() );
+}
+
+void
+test02()
+{
+  bool test __attribute__((unused)) = true;
+  using namespace std;
+
+  set<int> s0;
+  typedef set<int>::iterator iterator;
+  typedef set<int>::const_iterator const_iterator;
+  typedef pair<iterator, bool> insert_return_type;
+
+  insert_return_type irt0 = s0.insert(1);
+  s0.insert(2);
+  insert_return_type irt2 = s0.insert(3);
+  insert_return_type irt3 = s0.insert(4);
+
+  iterator pos1 = s0.erase(irt0.first, irt2.first);
+  VERIFY( pos1 == irt2.first );
+
+  iterator pos2 = s0.erase(irt2.first, ++irt3.first);
+  VERIFY( pos2 == s0.end() );
+}
+
+int
+main()
+{
+  test01();
+  test02();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/abi_tag.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/abi_tag.cc
new file mode 100644
index 0000000..e612b2c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/abi_tag.cc
@@ -0,0 +1,38 @@ 
+// { dg-do compile }
+// { dg-options -std=c++11 }
+
+// Copyright (C) 2013 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+// Test that the C++11 variants have an ABI tag
+
+#include <set>
+
+using container = std::set<int>;
+using iterator = typename container::iterator;
+using const_iterator = typename container::const_iterator;
+
+// { dg-final { scan-assembler "_ZNSt3setIiSt4lessIiESaIiEE5eraseB5cxx11ESt23_Rb_tree_const_iteratorIiE" } }
+iterator (container::*p1)(const_iterator) = &container::erase;
+
+// { dg-final { scan-assembler "_ZNSt3setIiSt4lessIiESaIiEE5eraseB5cxx11ESt23_Rb_tree_const_iteratorIiES5_" } }
+iterator (container::*p2)(const_iterator, const_iterator) = &container::erase;
diff --git a/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/dr130-linkage-check.cc b/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/dr130-linkage-check.cc
new file mode 100644
index 0000000..a894f0c
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/modifiers/erase/dr130-linkage-check.cc
@@ -0,0 +1,40 @@ 
+// { dg-require-effective-target ia32 }
+// { dg-require-sharedlib "" }
+// { dg-options "-fno-inline -std=gnu++11 ./testsuite_shared.so" }
+// 2013-06-03  Benjamin Kosnik  <bkoz@redhat..com>
+//
+// Copyright (C) 2013 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/>.
+
+#include <testsuite_containers.h>
+
+int main()
+{
+  typedef std::set<int>			container_type;
+
+  {
+    container_type s { 0, 1, 2 };
+    __gnu_test::linkage_check_cxx98_cxx11_erase(s);
+  }
+
+  {
+    container_type s { 0, 1, 2 };
+    __gnu_test::linkage_check_cxx98_cxx11_erase_iterators(s);
+  }
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
index d77c712..23c551b 100644
--- a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
+++ b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc
@@ -25,4 +25,4 @@ 
 
 #include <vector>
 
-// { dg-error "multiple inlined namespaces" "" { target *-*-* } 269 }
+// { dg-error "multiple inlined namespaces" "" { target *-*-* } 275 }
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 5d0a2ff..51ff6dd 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -626,7 +626,7 @@  proc v3-build_support { } {
 	    # Compile with "-w" so that warnings issued by the compiler
 	    # do not prevent compilation.
 	    if { [v3_target_compile $srcdir/util/$f $object_file "sharedlib" \
-	     [list "incdir=$srcdir" "additional_flags=-w -shared -fPIC -DPIC"]]
+	     [list "incdir=$srcdir" "additional_flags=-fno-inline -w -shared -fPIC -DPIC"]]
 		 != "" } {
 		error "could not compile $f"
 	    }
diff --git a/libstdc++-v3/testsuite/util/testsuite_containers.h b/libstdc++-v3/testsuite/util/testsuite_containers.h
index 723f8ad..7e41d05 100644
--- a/libstdc++-v3/testsuite/util/testsuite_containers.h
+++ b/libstdc++-v3/testsuite/util/testsuite_containers.h
@@ -223,6 +223,58 @@  namespace __gnu_test
   template<typename _Tp>
   _Tp citerator<_Tp>::_S_container;
 
+  // DR 130 vs. C++98 vs. C++11.
+  // Defined in testsuite_shared.cc.
+  void 
+  erase_external(std::set<int>& s);
+
+  void 
+  erase_external(std::multiset<int>& s);
+
+  void 
+  erase_external(std::map<int, int>& s);
+
+  void 
+  erase_external(std::multimap<int, int>& s);
+
+  void 
+  erase_external_iterators(std::set<int>& s);
+
+  void 
+  erase_external_iterators(std::multiset<int>& s);
+
+  void 
+  erase_external_iterators(std::map<int, int>& s);
+
+  void 
+  erase_external_iterators(std::multimap<int, int>& s);
+
+// NB: "must be compiled with C++11"
+#if __cplusplus >= 201103L
+template<typename _Tp>
+  void 
+  linkage_check_cxx98_cxx11_erase(_Tp& container)
+  {
+    // Crashing when exteral reference and internal reference symbols are
+    // equivalently mangled but have different size return types in C++98
+    // and C++11 signatures.
+    erase_external(container); 		// C++98
+    container.erase(container.begin());	// C++11
+  }
+
+template<typename _Tp>
+  void 
+  linkage_check_cxx98_cxx11_erase_iterators(_Tp& container)
+  {
+    // Crashing when exteral reference and internal reference symbols are
+    // equivalently mangled but have different size return types in C++98
+    // and C++11 signatures.
+    erase_external_iterators(container);// C++98
+
+    auto iter = container.begin();
+    container.erase(iter, ++iter);	// C++11
+  }
+#endif
 
 } // namespace __gnu_test
 
diff --git a/libstdc++-v3/testsuite/util/testsuite_shared.cc b/libstdc++-v3/testsuite/util/testsuite_shared.cc
index ed7f471..e07a03e 100644
--- a/libstdc++-v3/testsuite/util/testsuite_shared.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_shared.cc
@@ -19,9 +19,13 @@ 
 #include <stdexcept>
 #include <iostream>
 #include <sstream>
+#include <set>
+#include <map>
 #include <ext/mt_allocator.h>
 #include <bits/functexcept.h>
 
+namespace __gnu_test
+{
 // libstdc++/22309
 extern "C" void
 try_allocation()
@@ -70,3 +74,57 @@  try_function_random_fail()
   // Randomly throw. See if other threads cleanup.
   std::__throw_bad_exception();
 }
+
+#if __cplusplus < 201103L
+// "must be compiled with C++98"
+  void 
+  erase_external(std::set<int>& s)
+  { s.erase(s.begin()); }
+
+  void 
+  erase_external(std::multiset<int>& s)
+  { s.erase(s.begin()); }
+  
+  void 
+  erase_external(std::map<int, int>& s)
+  { s.erase(s.begin()); }
+  
+  void 
+  erase_external(std::multimap<int, int>& s)
+  { s.erase(s.begin()); }
+
+  void 
+  erase_external_iterators(std::set<int>& s)
+  {
+    typedef typename std::set<int>::iterator iterator_type;
+    iterator_type iter = s.begin();
+    s.erase(iter, ++iter);
+  }
+
+  void 
+  erase_external_iterators(std::multiset<int>& s)
+  {
+    typedef typename std::multiset<int>::iterator iterator_type;
+    iterator_type iter = s.begin();
+    s.erase(iter, ++iter);
+  }
+
+  void 
+  erase_external_iterators(std::map<int, int>& s)
+  {
+    typedef typename std::map<int, int>::iterator iterator_type;
+    iterator_type iter = s.begin();
+    s.erase(iter, ++iter);
+  }
+
+  
+  void 
+  erase_external_iterators(std::multimap<int, int>& s)
+  {
+    typedef typename std::multimap<int, int>::iterator iterator_type;
+    iterator_type iter = s.begin();
+    s.erase(iter, ++iter);
+  }
+#endif
+
+} // end namepace __gnu_test