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

    <tr>
        <th>Summary</th>
        <td>
            std::allocate_shared & std::make_shared for arrays causes new-delete-size-mismatch under asan 
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

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

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

<pre>
    The following snippet yields a new/delete type mismatch when building with sized deallocation:

```c++
int main(int argc, char *argv[]) {
 std::allocate_shared<int64_t[]>(std::allocator<int64_t>{}, 1);
}
```

It runs fine with `-stdlib=libc++ -fsanitize=address -std=c++20`, but fails when adding `-fsized-deallocation`. Asan stack trace:
```
=================================================================
==1==ERROR: AddressSanitizer: new-delete-type-mismatch on 0x504000000050 in thread T0:
  object passed to delete has wrong type:
  size of the allocated type:   40 bytes;
  size of the deallocated type: 320 bytes.
    #0 0x561aa17a18d2 in operator delete(void*, unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3
    #1 0x561aa17a4f6c in void std::__1::__libcpp_operator_delete[abi:v180000]<void*, unsigned long>(void*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:282:3
 #2 0x561aa17a4f0c in void std::__1::__do_deallocate_handle_size[abi:v180000]<>(void*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:308:10
 #3 0x561aa17a4eb4 in std::__1::__libcpp_deallocate[abi:v180000](void*, unsigned long, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:322:14
 #4 0x561aa17a4e39 in std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>::deallocate[abi:v180000](std::__1::__sp_aligned_storage<8ul>*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator.h:130:13
 #5 0x561aa17a4df4 in std::__1::allocator_traits<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::deallocate[abi:v180000](std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>&, std::__1::__sp_aligned_storage<8ul>*, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator_traits.h:288:13
 #6 0x561aa17a4586 in std::__1::__unbounded_array_control_block<long [], std::__1::allocator<long>>::__on_zero_shared_weak() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1140:9
 #7 0x561aa17a50ee in std::__1::__shared_weak_count::__release_shared[abi:v180000]() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:215:9
 #8 0x561aa17a31a5 in std::__1::shared_ptr<long []>::~shared_ptr[abi:v180000]() /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:775:23
 #9 0x561aa17a305b in main /app/example.cpp:5:5
    #10 0x7f028f312082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)
    #11 0x561aa16c536d in _start (/app/output.s+0x2c36d)

0x504000000050 is located 0 bytes inside of 40-byte region [0x504000000050,0x504000000078)
allocated by thread T0 here:
    #0 0x561aa17a0c6d in operator new(unsigned long) /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
    #1 0x561aa17a3af4 in void* std::__1::__libcpp_operator_new[abi:v180000]<unsigned long>(unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:272:10
 #2 0x561aa17a3a5c in std::__1::__libcpp_allocate[abi:v180000](unsigned long, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/new:298:10
 #3 0x561aa17a399c in std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>::allocate[abi:v180000](unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator.h:114:38
 #4 0x561aa17a392c in std::__1::allocator_traits<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::allocate[abi:v180000](std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocator_traits.h:268:20
 #5 0x561aa17a3626 in std::__1::__allocation_guard<std::__1::allocator<std::__1::__sp_aligned_storage<8ul>>>::__allocation_guard[abi:v180000]<std::__1::allocator<long>>(std::__1::allocator<long>, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/allocation_guard.h:57:18
 #6 0x561aa17a3317 in std::__1::shared_ptr<long []> std::__1::__allocate_shared_unbounded_array[abi:v180000]<long [], std::__1::allocator<long>>(std::__1::allocator<long> const&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1162:39
 #7 0x561aa17a30f7 in std::__1::shared_ptr<long []> std::__1::allocate_shared[abi:v180000]<long [], std::__1::allocator<long>, void>(std::__1::allocator<long> const&, unsigned long) /opt/compiler-explorer/clang-trunk-20231002/bin/../include/c++/v1/__memory/shared_ptr.h:1301:12
 #8 0x561aa17a3052 in main /app/example.cpp:5:5
    #9 0x7f028f312082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)

SUMMARY: AddressSanitizer: new-delete-type-mismatch /root/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3 in operator delete(void*, unsigned long)
```

Live snippet: https://godbolt.org/z/ddYr6TYb1

Note: the mismatch was found by running the [`std::boyer_moore_searcher` example snippet on cppreference](https://en.cppreference.com/w/cpp/utility/functional/boyer_moore_searcher): https://godbolt.org/z/Gsx6dWPYn. Likely it has the same underlying issue, although this one does not require c++20 to reproduce.

The [allocation](https://github.com/llvm/llvm-project/blob/824b1677a44e25b7c9808c774ba2d894ff14df2b/libcxx/include/__memory/shared_ptr.h#L1162) divides by `sizeof(_AlignedStorage)`, but the [deallocation](https://github.com/llvm/llvm-project/blob/824b1677a44e25b7c9808c774ba2d894ff14df2b/libcxx/include/__memory/shared_ptr.h#L1140) does not appear to make the same adjustment. That may be the source of the issue, which could be fixed w/ something like:

```diff
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -1137,7 +1137,9 @@
 __alloc_.~_Alloc();
         size_t __size = __unbounded_array_control_block::__bytes_for(__count_);
 _AlignedStorage* __storage = reinterpret_cast<_AlignedStorage*>(this);
- allocator_traits<_StorageAlloc>::deallocate(__tmp, _PointerTraits::pointer_to(*__storage), __size);
+ allocator_traits<_StorageAlloc>::deallocate(
+            __tmp, _PointerTraits::pointer_to(*__storage),
+            __size / sizeof(_AlignedStorage));
     }
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWl1v2zgW_TXMC2GDIvX54AcnqRcDdHYHbRaLPgmUSFmcyKSWpJK4D_PbB1eSbTmxk6btNK3hOIbEj3vOPSSPSHPn1FpLuUDRJYquL3jna2MXtmtbK8vaXxRGbBc3tcSVaRpzr_QaO63aVnq8VbIRDnOs5T2iKyEb6SX221bijXIb7ssa39dS46JTjYCa98rX2KnPUmAhedOYkntlNGJLRK4R2X3GZHiXiF7Cu7-qtMcbrjSiKXzldl0ieoXLmluM6JLb9d2AAdEMo2SshZ0X0Dxbjt3J3NXcSoHYldI-DnM_1mLvEE0flzZ2Uo69g2aTa-g2QDRDbOwErh1HPoXzm8e20w5XSsuBARSTmfOiUQVi140qRpx4VjmulVefJWLXXAgrncOzPqbrsQztW6dXuOg8rrhq3EAxFz3B0HLVEzw7Ijgmc7x0XGPneXmLveWlPLD-KGp2_cu_J0CC4d-7Dx_-8wGxJV4OvH4cmbZwTcv72SDfGch3tpev0Zg8RCQkwysiWGnsayu5wDdkzyDGpvhTlh633DkpsDd4HA01d_jeGr3ux8WkAiQJmwr7WuKdNMWuEMY4JLjYeun2Ijuuss_upBKjY535rgbGiDICEOKA8yDhQSooQDCttKDuMUxE0zujBKJLkFan-zlB4MbodT-a6Moa4xFdNc3dZtZaA2ARXZVm06pG2pntb6oC0RV3XI__ci3v86GHedm2iC2DOERsyY7iCybxhVVcQnwQzWHo5nmw-wKjpW3zXfxj6yi65IVCbHkXpJCnfjxfnYXUD_UXAJv2CKB8aBtjpYVrDdfrmbedvp1RQllACEV0VcDUtJrPEV0pXTadkFB2nMHo6i5AdAUTJVvSlE5IQJTRIwbI8wwIkx-Sn9dci0bmII3TJLw1WEZSyDs5oGVTtLIIAe0zqT6APQXwOWg_HiuFxAbhAWt4hJVlp7FOF5tTTLg2500PJHfeWL6WiF2lXQO5hTeUeomm17b7g8WS5xu5MXYLM8eOjXkNbDLSfx44jaaciuqMfvat5N5y5d1Jar-V-K_m_hs7pjEk5xdM6ZiMPrM0TR9lNp5mNkrjczNDpwvTaSFFzq3l27w02lvT5EVjylvErgAZ3pnBUzxN6d-tCLtk5rnR-WdpzWgU83vJbxFNfxBVY6etH-UfhKD_7EBSMiEpIlKeI2kSfV6aTvvdDSsbyd3eB59U7NuApUF0jDWdYGUBj05jPbTyKPe7lP41KfETwU0SgEsnAyCb4iVRAXjhmQeC422L6Eo-8E3b7OxU1P8dmSlwe0lFaFqxgJK0d3vDWpo7z63Px_bSvWF7SOM8DmeN0t3DbK274UY5d2YeI3pJHmhIUjpQlF7Co9xvkAEcpEkq4yJMooSSMimjIIszGWe8oIImccVlLAIhJTwpHYV4MHxxGbFY9CH2wY1xDVBN59vOz90QQ8lisW9p-HzszB3eOeLRB2OlnRK9Zw7JDC5hK9fKaBDIcW1Er6YXknTf18FnF9uD9ce1tFM7_8Rpk3IAtnfa_UNy-g966yx61lozPiyVo1_6IncNMZ90lSf89I820Ql95CvpEdiofMFXPr9kv7WVpNlztpll2Rl438NKvoqZt7CEQf8QmZ622SyjL3HzAyzhmxjCn8faxaBeSk6bdhbTs9busGeVrztuxT-ZoxO9nZzsvtg_vpTY_WT5pqnao-1TFSUwotLTJpyxIHm153ourzvX-djCnyb-a338F-YBl0Y7_4Zj54nXj_uNoTNmn5HquyTj8Ub496OeXg3u4hdOASMQbEDPPIOQiL7ek2c_ryUfPj_-9_fflx8-vXp3_LvvC796a_qZY5f36k7ujqoARe1960CIdIXoam1EYRo_N3aN6OozoishPtn45lMRTBv5t_H91rqvp2da3OEKZi94IrCd1kqv-xIwXmKyF35httLmG2OszJ3ktqylRTHBo17252hG47JtrayklbqUg0U4Dlfq-bTIvDQbRFf3QHUvwc6rRnkQdNXpEqZ43sBgOBUBzb6Ejn-5h1j8749Peo7fq1vZbLHy_WkGAHV8IzFM37bZAnjlXCchP7zxtenWNfa1cthoiYWRDmvjsZX_75SVeH-Qhb3BVrbWiK6U8ynrNwOXk_OrE5Ssla-7YmQC9PdUhkVjQHkpDYsgThIehpJGRVJmKUnLJAkLTkWahVUVhKKixTjKHh6O5o5zkwVl7_sJm2ZYqDslpAM5QP7VZ2kqRNN8OZiQj6MHodnk7G7Uy9Ep3c-KMiQ9yl0medtKbiF9G34rD4Lg4s_O-Y3Ufo5vau7xhm9xMRYwnS33p1d7vdzXqqxxabpGQMlKPUiBQdbYmY30NYirUbfy3AmxUFU1XJrNZpi_DtvQ1LgyXOJXMjPUDgkKCZ4FAUsQvUowopfj9wwPN8elYLRA-fyvfAlfhl2nyene-AL15B7n_ZEORuwav7jfOSyy_Y5HXhkLyht2_PKjHp7IEYIa_XHfkZVKe2lbK31ecucRu3paZ1jcYXhPG5_hEw9X-VhrwHtisxwC9ZsWhJD_YfrOb8bKULIdLuXe9GQt99FCz1BnOPaaHsTTy68M5FB_8vqW6M40OGQV9P3MLPFYF09_X3AhFkxkLOMXchHEWUwzEmbJRb0IKxkGJElKHlVZFPGYxxXLYloVUcojXl2oxc4sURamQTInPJJlRTNWsbSKwhiFRG64auYwzcCCcNGP1kWckii4aHghG9f_WoTSw08XEKUour6wi35uKrq1QyFplPPu0IxXvpGLc7_HwIjGB5sJE8vuRmUs7nXvcMk7B5PQwZAAjQdD0i9JGCwGvuhss3j1XNpDdYiuerR_BwAA___Jf5Wi">