<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/112362>112362</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libc++] strong exception safety not guaranteed by std::vector<T,Allocator>::insert
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          futog
      </td>
    </tr>
</table>

<pre>
    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
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vs1yozgQfhr50hUKBAZz4ODY430Bz9klhDCalZFLEk48T7_VAv9gk0myW-siBEn9dX_9o5aYtXLfClGQ-SuZr2esc402Rd05vZ-VujoX20ZArZXSb7LdA9eVIOGahMvhnYbD0w9pLFuuukoAiVfWVeKdi6Mj8Y-p9ZPgTpsPFjmzVpg76LQBqYPmQUa2DrjuWgckXkNI4tf7VScOR8Wcx7vzUbTsIGB7VWGd6biDklU7ppTmQLIBDgCAgErUsIUTU53Y4fiqHwWsq0i8JPHSg5l3b4XawU88cBkhrPwtdg4O7H2Hn4QuCM2B69a6MQn8GeE600IUhuHIPsnWjwbuHeaKWQs_CV2B_wyCAJZmb6_uI-CkZdXbxVAQuvhJ6BKOCPKyNCU0RSTzo_yZnayB0IXPwcsL2u0TQXNwjdFvQBc30s8R2znDpLN9fqej6R9cuKfZR5iuPNVH7bU2b8xUJF5d_KWLgX8QBITmn4XRR6USAxNMz_YalscctpNRGXLmNQQjTV5J-xkJb-8O9S-s3qHH5iYc_oK51VCeGBuUbmTrvktidUF94Hu2_t4GLrVWoI_C9OWyxgdrEXled_WljGgKqrE3R6YETPNc5IM_znS37f8Qwm_RpNH_SbNmyn7IE7vlgcl26Dcj_K2L5tNd7tLBVz6FqxExnIp_AP6d-Ah-4oERVpgTlkDymHpnzs8FROjG77bONruS8b-B0CXOjYROPLgKELqIHzV_KvOfFVzY9qPhBKOLEw_uWnpflPDkOP7uIZwdGZfu_CfYVf6aKpSZT5LCEG7ANdKCbBHWd2N7c76f7q2XYn8rCvoKEeaX4uvJZZKtgTPHG-z6WE9isglcuYoLT6_9jzH4QtgmWtfldJyo-fF9pWZSWXiTroHJ9aWnInULJA0_opMBqhHV9I3Iv7fCOlGBbuF9ke7SBLAzWEfiJTTOHS3uJp-eva5KrVygzZ7QzW9CN9lfv2yTi7SeVUVc5XHOZqKIMpqHYUSjbNYUaRTmIkzqusxiloRJlrGM8pKLeb1YRGU1kwUNaRKF0TxKwnSeBXORJKymdZmLPJuXJUlCcWBSBUqdDmh7Jq3tRBFFNE7pTLFSKHu5IpoCpV7Kbm9JEippnb3hnHTKXyaVLDmhr_jM12Cd0e0e-tsghtOyWrgztNrBvmOGtU6ICsrzRGvZErpa3s7_4eDvS3XWGVU8RFC6pisDrg-EbpDX8O_laPQvgReFjXfOEroZ_DsV9J8AAAD__5ZyEEA">