re PR libstdc++/56613 (map::operator[](key_type&&) fails with custom allocator)
authorJonathan Wakely <jwakely.gcc@gmail.com>
Thu, 14 Mar 2013 23:28:11 +0000 (23:28 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 14 Mar 2013 23:28:11 +0000 (23:28 +0000)
PR libstdc++/56613
* include/bits/stl_tree.h (_Rb_tree::_M_create_node): Use
allocator_traits instead of calling construct directly.
* testsuite/23_containers/map/56613.cc: New.

From-SVN: r196666

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/testsuite/23_containers/map/56613.cc [new file with mode: 0644]

index fd4b2f93f258c54a3430a33297998a7b0ff69be9..65ed5fca38c0ae4733dc89d2c2f0fe5790af614d 100644 (file)
@@ -1,3 +1,10 @@
+2013-03-14  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+       PR libstdc++/56613
+       * include/bits/stl_tree.h (_Rb_tree::_M_create_node): Use
+       allocator_traits instead of calling construct directly.
+       * testsuite/23_containers/map/56613.cc: New.
+
 2013-03-13  Benjamin Kosnik  <bkoz@redhat.com>
 
        * doc/html/*: Regenerate.
index 59883fca834d762f3c8576473687922c36766dd8..cb5a8eff800e7ea414020deb5ba81b9b7bc15594 100644 (file)
@@ -62,6 +62,9 @@
 #include <bits/allocator.h>
 #include <bits/stl_function.h>
 #include <bits/cpp_type_traits.h>
+#if __cplusplus >= 201103L
+#include <bits/alloc_traits.h>
+#endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -400,8 +403,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          _Link_type __tmp = _M_get_node();
          __try
            {
-             _M_get_Node_allocator().construct(__tmp,
-                                            std::forward<_Args>(__args)...);
+             allocator_traits<_Node_allocator>::
+               construct(_M_get_Node_allocator(), __tmp,
+                         std::forward<_Args>(__args)...);
            }
          __catch(...)
            {
diff --git a/libstdc++-v3/testsuite/23_containers/map/56613.cc b/libstdc++-v3/testsuite/23_containers/map/56613.cc
new file mode 100644 (file)
index 0000000..9843359
--- /dev/null
@@ -0,0 +1,74 @@
+// -*- C++ -*-
+
+// 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_hooks.h>
+#include <map>
+
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+
+// libstdc++/56613
+#include <map>
+
+// A conforming C++03 allocator, should still work in C++11 mode.
+template<typename T>
+struct alloc
+{
+    typedef T value_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef T& reference;
+    typedef const T& const_reference;
+    typedef unsigned size_type;
+    typedef int difference_type;
+
+    template<typename U>
+        struct rebind {
+            typedef alloc<U> other;
+        };
+
+    alloc() { }
+    template<typename U>
+        alloc(const alloc<U>&) { }
+
+    pointer allocate(size_type n, const void* = 0) { return
+std::allocator<T>().allocate(n); }
+    void deallocate(pointer p, size_type n) { std::allocator<T>().deallocate(p,
+n); }
+
+    size_type max_size() const { return -1; }
+
+    void construct(pointer p, const T& t) { new ((void*) p) T(t); }
+    void destroy(pointer p) { p->~T(); }
+
+    pointer address(reference x) const throw() { return &x; }
+    const_pointer address(const_reference x) const throw() { return &x; }
+};
+
+template<typename T, typename U>
+bool operator==(alloc<T>, alloc<U>) { return true; }
+
+template<typename T, typename U>
+bool operator!=(alloc<T>, alloc<U>) { return false; }
+
+int main()
+{
+  std::map<int, int, std::less<int>, alloc<int> > m;
+  m[1];
+}