-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Open
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Description
I believe the following reproducer demonstrate an UB in std::vector
implementation of operator=
incase if we are using a custom allocator:
#include <vector>
#include <iostream>
#include <cstdlib>
// Simple custom allocator that checks it's not default-constructed
template <typename T>
class CustomAllocator {
public:
using value_type = T;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
CustomAllocator() : valid_(false) {}
CustomAllocator(bool valid) : valid_(valid) {}
template <typename U>
CustomAllocator(const CustomAllocator<U>& other) : valid_(other.valid_) {}
T* allocate(std::size_t n) {
if (!valid_) {
std::cerr << "Allocate called on invalid allocator\n";
std::abort();
}
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t n) {
if (!valid_) {
std::cerr << "Deallocate called on invalid allocator\n";
std::abort();
}
::operator delete(p);
}
bool operator==(const CustomAllocator&) const = default;
private:
bool valid_;
};
int main() {
CustomAllocator<int> alloc(true);
std::vector<int, CustomAllocator<int>> v1(alloc);
std::vector<int, CustomAllocator<int>> v2;
v1.push_back(1);
v2 = v1;
return 0;
}
The problem is observed at runtime. when v2 is constructor we do not call allocator, but when v2 is assigned we invoke deallocate with (nullptr, 0)
. This is UB I believe and should be adressed in the library.
Metadata
Metadata
Assignees
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.