<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - std::map does not call allocator_type::destroy for elements if the map moves to another map and their allocators are not equal"
   href="http://llvm.org/bugs/show_bug.cgi?id=22366">22366</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>std::map does not call allocator_type::destroy for elements if the map moves to another map and their allocators are not equal
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>All Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>kariya_mitsuru@hotmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=13747" name="attach_13747" title="g++ -v">attachment 13747</a> <a href="attachment.cgi?id=13747&action=edit" title="g++ -v">[details]</a></span>
g++ -v

Please see the sample code below. (Sorry, too long)

===================================== sample code
=====================================
#include <map>
#include <utility>
#include <iostream>

template <typename T>
struct MyAlloc {
    typedef T value_type;
    MyAlloc(int i = 0) : i(i) {}
    template <typename U>
    MyAlloc(const MyAlloc<U>& o) : i(o.i) {}
    T* allocate(std::size_t n) {
        void* p = ::operator new(sizeof(T) * n);
        std::cout << "allocate:" << p << std::endl;
        return static_cast<T*>(p);
    }
    void deallocate(T* c, std::size_t) {
        void* p = c;
        std::cout << "deallocate:" << p << std::endl;
        ::operator delete(p);
    }
    template <typename U, typename... Args>
    void construct(U* c, Args...args) {
        void* p = c;
        std::cout << "construct:" << p << std::endl;
        ::new(p) U(std::forward<Args>(args)...);
    }
    template <typename U>
    void destroy(U* p) {
        std::cout << "destruct:" << static_cast<const void*>(p) << std::endl;
        p->~U();
    }
    int i;
};

template <typename T>
inline bool operator==(const MyAlloc<T>& lhs, const MyAlloc<T>& rhs)
{
    return lhs.i == rhs.i;
}

template <typename T>
inline bool operator!=(const MyAlloc<T>& lhs, const MyAlloc<T>& rhs)
{
    return lhs.i != rhs.i;
}

struct T {
    T(int i) : i(i) {
        std::cout << "T(int):"
                  << static_cast<const void*>(this) << '(' << i << ')' <<
std::endl;
    }
    T(const T& o) : i(o.i + 10) {
        std::cout << "T(const T&):"
                  << static_cast<const void*>(&o) << '(' << o.i << ") -> "
                  << static_cast<const void*>(this) << '(' << i << ')' <<
std::endl;
    }
    T& operator=(const T& o) {
        i = o.i + 30;
        std::cout << "operator=(const T&):"
                  << static_cast<const void*>(&o) << '(' << o.i << ") -> "
                  << static_cast<const void*>(this) << '(' << i << ')' <<
std::endl;
        return *this;
    }
    ~T() {
        std::cout << "~T():"
                  << static_cast<const void*>(this) << '(' << i << ')' <<
std::endl;
    }
    int i;
};

int main()
{
    using map = std::map<int, T, std::less<int>, MyAlloc<std::pair<const int,
T>>>;

    std::cout << "1" << std::endl;
    map m1;
    m1.emplace(1, 2);
    std::cout << "2" << std::endl;
    map m2(std::move(m1), MyAlloc<map::value_type>(1));
    std::cout << "3" << std::endl;
}
===================================== sample code
=====================================

======================================= output
=======================================
1
allocate:0xd1f010
construct:0xd1f02c
T(int):0xd1f030(2)
2
allocate:0xd1f040
T(const T&):0xd1f030(2) -> 0x7fff2c3c7714(12)
construct:0xd1f05c
T(const T&):0x7fff2c3c7714(12) -> 0xd1f060(22)
~T():0x7fff2c3c7714(12)
deallocate:0xd1f010
3
destruct:0xd1f05c
~T():0xd1f060(22)
deallocate:0xd1f040
======================================= output
=======================================

cf. <a href="http://melpon.org/wandbox/permlink/JDPKzTVRwMq9zYZl">http://melpon.org/wandbox/permlink/JDPKzTVRwMq9zYZl</a>


The output shows that destroy for 0xd1f02c (and ~T() for 0xd1f030(2)) is not
called but deallocate for 0xd1f010 is called.

I think that the destroy (and destructor) should be called.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>