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

    <tr>
        <th>Summary</th>
        <td>
            [Clang] The assignment to object outside its lifetime is not allowed in a constant expression error while initializing heap allocated memory
        </td>
    </tr>

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

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

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

<pre>
    Below I wrote down a simplified version of the code I try to implement in the production environment.
The code below is compiled with the latest GCC and the latest MSVC.
Minimal reproducible example here: [https://godbolt.org/z/za3vKnxzj](url)

```cpp
#include <bit>
#include <cstddef>
#include <memory>
#include <iostream>

struct buffer
{
        constexpr buffer(char16_t const* values, size_t const count)
 : m_byte_count {count * sizeof(char16_t)}
        , m_bytes {std::allocator<std::byte>().allocate(m_byte_count)}
        {
                struct bytes
                {
                        std::byte bytes[2];
                };

                for (std::size_t index = 0; index < count; ++index)
                {
                        bytes const bitwise = std::bit_cast<bytes>(values[index]);
                        m_bytes[(index * sizeof(char16_t)) + 0] = bitwise.bytes[0];
                        m_bytes[(index * sizeof(char16_t)) + 1] = bitwise.bytes[1];
                }
        }

        constexpr auto compute() const -> int
        {
                int result = 0;
                for (std::size_t index = 0; index < m_byte_count; ++index)
                {
                        result = result ^ static_cast<int>(m_bytes[index]);
                }

                return result;
        }

        constexpr ~buffer()
        {
                std::allocator<std::byte>().deallocate(m_bytes, m_byte_count);
        }

        std::size_t m_byte_count;
        std::byte* m_bytes;
};

consteval auto compute(char16_t const* values, size_t const count) -> int
{
        buffer b(values, count);
        return b.compute();
}

auto main() -> int
{
        constexpr auto value = compute(u"oadpoadopa", 10);
        std::cout << value << std::endl;
        return 0;
}
```

```
<source>:53:17: error: constexpr variable 'value' must be initialized by a constant expression
   53 |         constexpr auto value = compute(u"oadpoadopa", 10);
      |                        ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:20:44: note: assignment to object outside its lifetime is not allowed in a constant expression
   20 | m_bytes[(index * sizeof(char16_t)) + 0] = bitwise.bytes[0];
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
<source>:47:9: note: in call to 'buffer(&u"oadpoadopa"[0], 10)'
   47 |         buffer b(values, count);
      |                ^~~~~~~~~~~~~~~~
<source>:53:25: note: in call to 'compute(&u"oadpoadopa"[0], 10)'
   53 | constexpr auto value = compute(u"oadpoadopa", 10);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:53:25: error: call to consteval function 'compute' is not a constant expression
   53 | constexpr auto value = compute(u"oadpoadopa", 10);
      | ^
<source>:20:44: note: assignment to object outside its lifetime is not allowed in a constant expression
   20 | m_bytes[(index * sizeof(char16_t)) + 0] = bitwise.bytes[0];
      | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
<source>:47:9: note: in call to 'buffer(&u"oadpoadopa"[0], 10)'
   47 |         buffer b(values, count);
      |                ^~~~~~~~~~~~~~~~
<source>:53:25: note: in call to 'compute(&u"oadpoadopa"[0], 10)'
   53 | constexpr auto value = compute(u"oadpoadopa", 10);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWEtv4zgS_jX0pdCGRFmWdfDBj2TRWPRpF3sNKLFks5cmDZKykxz6tw9IPf2aSTcyl8YIDiKRrOJXX31FUmLWip1CXJJ0TdLthNVur83y_0ZwVAWa3aTQ_G25RqnP8BXORjsErs8KGFhxOEpRCeRwQmOFVqArcHuEUnOEr-DMGzgNfhgeUDkQKnQfjeZ16bwBqpMwWvneKYlW_-2MizChsFDqw1FI5HAWbh-sJXNoHfxrswGm-Ljp23_-t_FevgklDkyCwWYmUUgEfGUeB-zRIElWQNL13rmjJcmK0GdCn3eaF1q6qTY7Qp_f_R9LTv9Wr-_fSboldFEbSWhOopX_zaPmVx6P_pEmQpWy5ggk2RTCkeTpprm0jnOs7nUd8KDN270eoa0zyA5tX7SyztSlg6KuKjS-KVuHjrzUyjp8PZqujy7KPTPx_MVB6CN0BScma7SEbsCKd-x6oNS1ck1w4Mk5vBRvDl9CM5Bs3d7QVTDT1ci3t8q23rC9vPPG3npT67inOFkxKXXJnDYk2fSNfpgPjS4IzaftECR0MUbQT0GivA-XRHlHhZ-qbxwPCGNGM7VD0zX1GU1GA7P-sW2ptAFCF715S5dQHF-BJFuISLLuHzctg8kaCF0Tug4dnVruwGroacgvhDsLi8HrAFe4l5JZ5-UUQAeS2vSlrX8vy_wijihvqff1TBctvkd5o7mHCxFJt2H2Fsm08xBd0_RL7uNH7uM7WWiTvO1zMcia1U6H9aAOCvHuGwK_kOQJhHK3ChHKgUFbS9fn7JczfKHIDyd6NHt3mz6BdcyJskuwhx7SO5D7KL8jYoJzVxvVOh7G3WXvR78qDGgvaunjZcrxplDtUPVDzd4DdE33FatXg8K8tFuPbDtgVKxNfCcmr9Xx00vfhYo6YhrOoBhKj27gJr42DcX0QpwD2IA04DswoVrp3pvuSuthyiCdwXFNKNWMHzXj-sgIpR5RHI3h9OyVuvbK23j1dr7CQz8CFZfXYUQXwLt97mrb8_fJxuralEEYySpNSLKKM797oDFePisY4jkxI5jfhgnNAhRCMzjUfvVDEEo4waR4Rw7FG7DGjikH3hatP1o0G0yaAMk23U4Dn8BXu2eNnF5dvlx_PLxueaARSVazmQ9faReOGs0hK5yAnAZdfMfSga6dFRxBOAtSVOjEAf2BR2kHvrzOyP156U_IoFHA_fcs-MH147ivWEifPsDMzIsjHxMjFJRMSs8KodlogZrfpq0F12ePZg0Ls-wiex-o2Icpvw3jgcxp-jiK8RrwE2G0yv5URd9Ly4ciGwq4jWtYZqtaNSf3cahZL9y_LN3PDvD3LcA-yn-q8HeuQtpUm4UdKjTMIZ-ON9oJXyY8T3I2wWWcJbNFNKNpNtkvywVfYFGUVcbmWVzSnFZxXlQsZtV8jkk8EUsa0VlMaRwvolmcTaOY4aKcJUk0TzHLKzKL8MCEnEp5OvjX3omwtsZlTKPFbD6RrEBpw4cBSkvJ1C4wt52YpTf4UtQ7S2aRFNbZwYUTToavCZtgkW7Bv9N_egE2pMF5L-To_CDUDvbIjtCdTzk0b9aT2sjl1eu-cPs6HNkIffbw239fjkZ7eIQ-Bzosoc8tI6cl_SMAAP__uPVBYw">