Skip to content

[libc++] strong exception safety not guaranteed by std::vector<T,Allocator>::insert #112362

Open
@futog

Description

@futog

The following code

#include <stdexcept>
#include <vector>
#include <cassert>

#include <stdio.h>

int count = 0;

template <typename T>
struct bad_alloc {
    typedef T value_type;
    std::allocator<T> alloc;

    std::size_t max_size() const {
        return 1000;
    }

    template <class U, class... Args>
    void construct(U* p, Args&&... args) {
        if (count-- <= 0) throw 28;
        std::allocator_traits<std::allocator<T>>::construct(alloc, p,
                std::forward<Args>(args)...);
    }

    void deallocate(T* p, std::size_t n) {
        return alloc.deallocate(p, n);
    }

    T* allocate(std::size_t n) {
        return alloc.allocate(n);
    }

    T* allocate(std::size_t n, const void* hint) {
        return alloc.allocate(n, hint);
    }
};

template <typename T>
bool operator==(const bad_alloc<T>& lhs, const bad_alloc<T>& rhs) {
    return true;
}

template <typename T>
bool operator!=(const bad_alloc<T>& lhs, const bad_alloc<T>& rhs) {
    return false;
}

int main() {
    count = 9;
    std::vector<int, bad_alloc<int> > vc;
    vc.reserve(4);
    try {
        /* push_back */
        vc.push_back(3);
        vc.push_back(3);
        vc.push_back(3);
        vc.push_back(3);
        
        assert(vc.size() == 4);
        assert(vc.capacity() == 4);
        assert(count == 5);
        // this insert throws
        vc.insert(vc.begin() + 1, 2, 3);
    } catch (int e) {
        assert(e == 28);
        assert(vc.size() == 4);
    }

    return 1;
}

fails with

Assertion `vc.size() == 4' failed

Tested on x86_64 latest: https://godbolt.org/z/7Gjsh9e6f

Metadata

Metadata

Assignees

No one assigned

    Labels

    exception-safetylibc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions