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

    <tr>
        <th>Summary</th>
        <td>
            std::use_facet doesn't check dynamic type
        </td>
    </tr>

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

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

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

<pre>
    ```c++
#include <locale>

int main()
{
  struct custom_ctype : std::ctype<char> { };
  (void) std::use_facet<custom_ctype>(std::locale());
}
```

using libc++ this program has a UBsan error:

```
/usr/bin/../include/c++/v1/__locale:254:12: runtime error: downcast of address 0x7fe687842e30 which does not point to an object of type 'const custom_ctype'
0x7fe687842e30: note: object is of type 'std::__1::ctype<char>'
 00 00 00 00  e8 77 83 87 e6 7f 00 00  01 00 00 00 00 00 00 00  c0 93 59 87 e6 7f 00 00  00 00 00 00
 ^~~~~~~~~~~~~~~~~~~~~~~
              vptr for 'std::__1::ctype<char>'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../include/c++/v1/__locale:254:12 in 
```

The implementation seems to assume that any facet with the right `id` is a match and just uses `static_cast`. This only work for standard facets, not user-defined ones.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVE2P4zYM_TXKhZhAlj3-OPiQzIxve-nuHHoKZImONWNLgSgnTQ_97YUc52O6iwJFBcE2TL5H6pGUJDJ7i1iz5y17fl3JKfTO1x8n-YnDedU6fa5Zzi9bMbGNm78yvmEiNVYNk0Zg6cvglByQpW-LcX4aG2CUxjJRMlEtlmLBA1DwkwqgJgpu3KlwPkSqDVDQLN2wdDP_YumL6qVn6RuwYguseGXpjYKJ8uiMZqK6oybCXScVhoh84I7JifLmtmR8SU1UN9IY4PJxPfbjkSYydg-DaRctIPSG4ODd3ssRekkg4X1L0gJ673wM9YD-J6VoJvJMNG3UqFmvmWgWTZlormqL5pgw0ex2V4034jlj6SYRUSw_2WBGvIUD7U5WSQrgOpBaeyQC_kfRYV4WZSYw5XDqjepBOySwLsDBxUIFB9KCaz9QzdhLOUShnKWvRWKiuOT_lTYGty7EBK80hh6ZbtLvdskvC3wjBs7vG7CEooAyhbIAzKHorgaefHG8IxSHKoXn6mfE3WuJxJ7f_vrlurbY4zoegofO-f92mu_v375tfvs96vJuNXbGot5iL4_G-e_SmmD-xLl009X61C5m-L8tAsbCv7Tzjx7BjIcBR7RBBuMsEOJIczcQTSNC6GUAac8wzxScTOgh9Aje7PsALOdGs5zHUksYZVA9SKvhY6IAEyFFD4rUahe7kuV8DT_izDg7nOHk_OcsKAVptfT6EoWYeJlbcyL0T4so4CzSeqXrVFdpJVdYJwXPiyrJq2rV12XVlryTotVZ22KVYdHJTJWoc6yKMmtXphZcZFzwJBFZmZRrVHmV6qQolE46KZBlHEdphvUwHMe18_uVIZqwLrko89UgWxxovieFsHiC2ciEiNemryPmqZ32xDI-GAp0ZwkmDFj_fD_NE2iZKAKoHtUn6LOVo1HzwKwmP9R9CAeKKNEw0exN6Kd2rdzIRBPZl9fTwbs4brE1Yk7ERDPn_HcAAAD__1g9wK8">