[LLVMbugs] [Bug 22366] New: std::map does not call allocator_type::destroy for elements if the map moves to another map and their allocators are not equal
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Tue Jan 27 20:12:21 PST 2015
http://llvm.org/bugs/show_bug.cgi?id=22366
Bug ID: 22366
Summary: std::map does not call allocator_type::destroy for
elements if the map moves to another map and their
allocators are not equal
Product: libc++
Version: unspecified
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: kariya_mitsuru at hotmail.com
CC: llvmbugs at cs.uiuc.edu, mclow.lists at gmail.com
Classification: Unclassified
Created attachment 13747
--> http://llvm.org/bugs/attachment.cgi?id=13747&action=edit
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. http://melpon.org/wandbox/permlink/JDPKzTVRwMq9zYZl
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.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150128/5c20e844/attachment.html>
More information about the llvm-bugs
mailing list