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

    <tr>
        <th>Summary</th>
        <td>
            clang 14/15 libc++: std::vector memory leak in case of iterator exception
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    The program below shows this memory leak when executed in Valgrind:
```console
[user@host]$ valgrind --leak-check=full ./LeakTest
==725012== Memcheck, a memory error detector
==725012== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==725012== Using Valgrind-3.20.0.GIT and LibVEX; rerun with -h for copyright info
==725012== Command: ./LeakTest
==725012==
Exceeded limit!
==725012==
==725012== HEAP SUMMARY:
==725012==     in use at exit: 40 bytes in 2 blocks
==725012==   total heap usage: 6 allocs, 4 frees, 1,272 bytes allocated
==725012==
==725012== 24 bytes in 1 blocks are definitely lost in loss record 2 of 2
==725012==    at 0x4C3761F: operator new(unsigned long) (vg_replace_malloc.c:432)
==725012==    by 0x10CF74: void* std::__1::__libcpp_operator_new[abi:v15002]<unsigned long>(unsigned long) (clang15el8/bin/../include/c++/v1/new:246)
==725012==    by 0x10CEFC: std::__1::__libcpp_allocate[abi:v15002](unsigned long, unsigned long) (clang15el8/bin/../include/c++/v1/new:272)
==725012==    by 0x10CE67: std::__1::allocator<unsigned int>::allocate[abi:v15002](unsigned long) (clang15el8/bin/../include/c++/v1/__memory/allocator.h:112)
==725012==    by 0x10CACC: std::__1::__allocation_result<std::__1::allocator_traits<std::__1::allocator<unsigned int> >::pointer> std::__1::__allocate_at_least[abi:v15002]<std::__1::allocator<unsigned int> >(std::__1::allocator<unsigned int>&, unsigned long) (clang15el8/bin/../include/c++/v1/__memory/allocate_at_least.h:54)
==725012==    by 0x10C852: std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >::__vallocate[abi:v15002](unsigned long) (clang15el8/bin/../include/c++/v1/vector:682)
==725012==    by 0x10C5E7: std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >::vector<MyIterator>(MyIterator, std::__1::enable_if<__is_cpp17_forward_iterator<MyIterator>::value&&is_constructible<unsigned int, std::__1::iterator_traits<MyIterator>::reference>::value, MyIterator>::type) (clang15el8/bin/../include/c++/v1/vector:1157)
==725012==    by 0x10C23C: main (main.cpp:57)
==725012==
==725012== LEAK SUMMARY:
==725012==    definitely lost: 24 bytes in 1 blocks
==725012==    indirectly lost: 0 bytes in 0 blocks
==725012==      possibly lost: 0 bytes in 0 blocks
==725012==    still reachable: 16 bytes in 1 blocks
==725012==         suppressed: 0 bytes in 0 blocks
==725012== Reachable blocks (those to which a pointer was found) are not shown.
==725012== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==725012==
==725012== For lists of detected and suppressed errors, rerun with: -s
==725012== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```

The program defines an iterator that at some point throws an exception in `operator*()`. Such behavior is common e.g. for Unicode iterators (UTF-8 and UTF-16) if they encounter illegal byte sequences (e.g. missing parts of surrogate pairs or incorrect leading/continuation bytes). It can be triggered with Boost.Regex when combined with the ICU library.
The iterator constructor of std::vector is used to actually trigger the memory leak.

Combinations where the leak occurs:

- clang 15.0.2 with libc++ (clang++ -Wall -Wextra -std=c++20 -stdlib=libc++ main.cpp -o LeakTest)
- clang 14.0.6 with libc++

Combinations where no leak occurs:

- clang 11.0.1 with libc++
- clang 14.0.6 with libstdc++ (clang++ -Wall -Wextra -std=c++20 -stdlib=libstdc++ main.cpp -o LeakTest)
- gcc 12.2 with libstdc++ (g++ -Wall -Wextra -std=c++20 main.cpp -o LeakTest)

This looks like a regression in recent versions of libc++. 

The program to reproduce the issue:

```c++
#include <iostream>
#include <vector>

class MyIterator
{
public:
    using iterator_category = std::forward_iterator_tag;
    using difference_type = std::ptrdiff_t;
    using value_type = unsigned int;
    using pointer = value_type*;
    using reference = value_type&;
    using const_reference = const value_type&;

    using ContainerType = std::vector<value_type>;
    using ContainerTypeConstIterator = typename ContainerType::const_iterator;

    const_reference operator*() const
    {
        static unsigned int s_counter = 0;
        if (++s_counter == 2U)
            throw std::runtime_error("Exceeded limit!");
        return *m_itValue;
    }

    bool operator==(const MyIterator&) const = default;

    MyIterator& operator++()
    {
        ++m_itValue;
        return *this;
    }

    static MyIterator begin(const ContainerType& p_values)
    {
        return MyIterator(p_values.begin(), p_values.end());
    }

    static MyIterator end(const ContainerType& p_values)
    {
        return MyIterator(p_values.end(), p_values.end());
    }

private:
    MyIterator(const ContainerTypeConstIterator& p_itValue, const ContainerTypeConstIterator& p_itEnd) : m_itValue(p_itValue), m_itEnd(p_itEnd)
    {
    }

    ContainerTypeConstIterator m_itValue;
    const ContainerTypeConstIterator m_itEnd;
};

int main()
{
    try
    {
        const std::vector<unsigned int> values{ 0, 1, 2, 3, 4, 5 };
        const std::vector<unsigned int> copy(MyIterator::begin(values), MyIterator::end(values));
    }
    catch (const std::runtime_error& e) {
        std::cout << e.what() << std::endl;
    }
    return 0;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy1WVtz4jgW_jXkRYXLFzDwwAMh0NO73btT6aRn98kl28JoY2zWlkny7-c78p1bk56eFEVAls7109F3hJ-G7_OnrWD7LI0yvmO-iNNXlm_T15yprczZTuzS7J3Fgr-w161ImHgTQaFEyGTCvvM4ymQSDpzFwHwYmIuBa5avIE3yNBbV6Pi-yEU2GJnbNFeD8cPAHrFDtZYNhyR8GGxF8DJwHjZFHDNjYK-_YPRJYH4pw3nAa2KPTcsuP7OvYlcuspeM14aKLEszFgolApVmF9cu0_17JqOtYgN7uhzYM2abpj20TdvW4mDXp389s0-_fxnYk5CG_Hf2jyKWPGHfxCvPQiYU47FxUcNzLpOoidDQMWzTMI1Pn5-08C_S_776z8C5Z5nIioS9SrVlwy3bwPigsU0mm_SKC7sd17G_KVzl-OotECJE9mK5k2pgW9enn1H722rxO_v2_PXr4vG_bd5P59EfIILEM66AGmiDpSMTgVQip0c28-M0eMmviFCp4jHbCr6HIB4JEuEi7FiXU1JGbJMJoT9aeLMndiVeT-GA6Yf9AzQbC63KQsYzAUxtZCKViLEbAGN6jv85EhikgIPN0g2zr4UDYTDfRktn4lprciTdi4wDpCwRr0BhkeQySig1aRIRIjF2iLxM7GMeCG-nXTICrBw5AOnsmiqA1XyzzOV6MiJNh1QCwwuWK71VnYXnWfWHWPrBfu_VxnhkzPie-xJPD9YYu4I2rLPsm-esLlgcxDyJrLGIp8CkLxO8GwRPmQRxEQp8Cgb2vX6tD8jZmvQ5C3vk3ujSar0kl664Uuf-jBsnNi_Zr3RicmteVu7kvBOV7ahcnYjLRFHAuxNucu7nfPG8spTiY2ONsYUmy7rVvcXyYo4qkTJNgOy8iOHZ8koYPJVxqfLrk05jxZp47VOM4OzB2BVzhMeVh2OITqcz2P-4bnv6sdza7i_D4mn-Wu90HsejG9M4Hdvn03goD9cjN-DATybJ8w5_P65roxfu9FYcj1cXtumvDkAj7-v7Z1UW4hJFne9npYuE-7Hw5AZrPU_mHgqgNfFAI4ijeLIRdiS51MrjQmjoubQSlE1lRaAkJN7kWi293aRnlGRiIzKRBOJY7ZKdma3e9-IvJ9iyxpMbM2w7ulLtOE5z6KT_BkJIu-SaiIuiv6wW_7yRHR3xCTLjHPe4JgLEUoJ-qI6IDr8yb5DA2B4cBhn_aQm5kiDsmeDBlmvgLJjlfswN_ZcX-z1OhFyEHzXisdZdszUkUqHTEKCP6FlksEV7UJ0D7JXnINkFeDNQRrQuSZXud5LLVP4pZbmAtK3YEWxbxk6WnmtfhkOSWD54QZKwNR5QBz6MpjXIYSxzlRO3LHsa7EfqH9polR1PfsawyxFbPT7--7EDU2SplAI6ne7wDbVAiTelQ3mcGD3FbDdH3fJVX_V7t6XUOCdKnrC6YCCUIMN45elOlKnBUEZNJ6cOMxB7YgiUfQiuqSkYLMwhxa5psG8F8uqLLT9ICESnGqAfwhphRIZuo54TGaShaJRqZ56f1sOpjiB9soh0Mrmh1KJ1TAIAg0ACRIsIjQdhEKn_f0H1S6_X0ncy183dnmdlavIC0YtwemFIQhEZBGEZ7U1qnUNJx9aaoiqTQrOfEt9Qb7DPigVw2wfC0PZFqJZh2Q_ep9iSxqOIxFvZe8NFFML6MYxmn5fPQIif8ezdaEPfxLmp6fhMdtYlvCyVFLWCIIR9wgNVAKLvtQ1aeqf5N7rpXWo7tB85WZbpzVFeEqRBUACOTe3T70OmqzmzxuiB7dJ8YutlAW-qffV1-AenTfQHEJhx4Jisfqjm2qYewGKMdUTUlZsNU9a0wjVGG_UjqHeP1f_AsyS9xTELkq3zki9ohxe_wP-OlB-EIAoCZtmd6PcNuFH5VSU1AoGrOE1RiWP5gvYfhSmiClJtaewKgQ1_EFmuwwxgtiEz2KU6ApCiF87SsAhKuGEXFuIoH-0FVC-3tlOxBlCupcSuwnm1I9Jx5nFNI1ZduUgPWv0OYSmfTSoF-8KPZdDYQudZoUtEQ5GI20a0maj-NvvwmKd5iqO3vj-WEspNRaI8Ikh9GXuV0XNPnVmoqVa7ps8_T2bXZyRNbVdS2T2d29C6k9numdm6Dnn9NXrswsrj9UtUTgBPZE8n7jfUuSOJ2OSJDT0ZS1JeJ1MLpIUJx3HUm1fqKM1vyfSJlcf-nRxZ5Yx2QYOchv4oFJ2glyFGnLxoMmL2fNL0b8O0dAJ6b66-x3putiXr_Oljto0eCIOSO-Hp418Ls0-vCG3dLx1rz4QqMmLNix1C812T-u6cweThOEx-msZtbErug9KngdDtdNwmYtpzMAiubwpO4t5b1Il62RZMexE4CXk57bzxfQfpJvxHvlUJbC3CgR5R11L514cVrN17GrH5dSMrI7qOTuuVRq2BRID_NeOC6G05Ovu43eXqv8_qjnU_YfM-kwe6J3AuwOCc4b3dXnpRJx0m3LpgVTYNul9s1087srRHu3rqtF10IVRn0nGlSp1H6o-sb-xpdg-U9ncS1Ro617s7pmenyt6vJLu04LQgH992VMCZ3FP3UF7YM_1ri6Ov8ultzLrWfVQB_XDSvzPR8-td0gL36O6hvEgJ-1MugFDbwxV6jwZql4qpy8qrjNNSH9bHSkEFbokX2pZX9ETVYVGNNRNhXHzZnGqzmb0M99nQnZhbrjueOdZsOrsL5044c2b8TkkVi3nNTtGhWOMue-1efVUdQ_fnQFC5gKPLBn9rGo6md7srsni-VWqvGbO9xisC7yx8A00MvsTxof43BKn7H8TT3Q5ROsR_PZ46M_tuOxdjcxS44wn3Q-GOrKk7m8KP6dSfhaEznkzuYu6LOJ8PxrDYTsRrxQptujm8k3P6Qc8yLdcajR1zZowsZ2pNuTs1uW_65nQwMgWQHxtkh5Fm0V021yb5RZTjoW6-24fggAQ4odVBPi_UNs3m-5d4NrnTiufa8D8B6Kqs-A">