<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/139589>139589</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang-tidy] Warn when `char` is passed to <ctype.h>/`<cctype>` function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang-tidy
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
s-barannikov
</td>
</tr>
</table>
<pre>
Quote from the latest C standard draft:
```
The header <ctype.h> declares several functions useful for classifying and mapping characters.
In all cases the argument is an int, the value of which shall be representable as an unsigned char
or shall equal the value of the macro EOF. If the argument has any other value, the behavior is
undefined.
```
Also see Notes [here](https://en.cppreference.com/w/cpp/string/byte/isalpha#Notes) for examples of invoking UB.
It would be nice to have a clang-tidy check that warns when the user calls a `ctype` function with a `char` argument.
It could also provide a fix-it hint to add a cast to `unsigned char`.
This is probably only relevant to platforms that have signed chars (most Linux platforms) or when `-fsigned-char` is used.
The check would be useful for libcxx, which doesn't cast the argument to `unsigned char` when calling those functions internally.
Most C library implementations work around this common mistake by extending character classification tables to include the range `[-128, -1]`, e.g.: [glibc](https://github.com/bminor/glibc/blob/2ae4ec56c2b18c46ef8220bcddac4303a4b6ef1c/ctype/ctype.h#L71), [picolibc](https://github.com/picolibc/picolibc/blob/560946f26db075c296beea5b39d99e6de43c9010/newlib/libc/ctype/ctype_.c#L38).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVV2r4zYQ_TXKyxAjyx-JH_KQu7uBhW1LoaWPZSSNY_XKkivJyc2_L7Kz9yZlKYVAZHtmdM6ZMxLGaM6O6MCaF9Z83uCcBh8OcSsxoHPm1V820uvb4dfZJ4I--BHSQGAxUUzwCWJCpzFo0AH7xKoj40fW8vuPH38bCAZCTQFY9Uml20TFwKovoElZDBQh0oUCWuhnp5LxLsIcqZ8t9D6AshlhfzPuDOg0jDhNea0GDKgShVgwfvzqAK0FhZHiAg_DeR7JJTAR0IFxiYlPy5cL2pnA93AdjBogDjlREgSaAkVyCaUlwCVtdos4etmN8aMP93j6e0b7XC4_jKiChy-_nAr42j_jGJaKN_BpoLBmfUckacCL8QFMZPw4O029caSLfwnJ-PFoo4dIBD_7RBFY8zJQINZ8ZmI_pDTFLL84MXEiV6hpCtRTIKeoUH5k4nRl4qSmiYlTTMG4MxMneUvExMlEtNOATFRLaSa6RX16w3GyFDNB4y7-NUv_-0uxwvma4Opnq7N8ziiC5GHACwHmtrnzNhl9AzWQeoU0YIIrBhfhOpBbiM-RAii0NgICa_liDtbydyfA1aTh_i13oOXvghbr_mrZH7MuU_AXo_PmvXnbmgSDcSlDQq0zIozLE2v5c1tbXiw2NTGbZQpeorQ38M7eIJClC65lJoup92GMK5eF6EOdCEzsRx8TfDNufvsIz1r6sLJmLd_2a9L2OyOz-F3fNc3jsir2Lu3DNFgj1dtbNs7qXu0pOiZ26U7v0XE_5rriyKLnVqbBR3oYPOMSBYfW3u5wfvLLkFsjA4YbmOyGXB3X-KsPr4DBz05DygoqP47ewWhiwlcCeQN6S-T008h-H2qjljKwjFzMgI1Tdta0EAnozpQpsOZlW4p9Zr0ts9lbntdUnAtWHfMUnLMuPxqDs0nDLO_ul6NxPuS3S7g4SeslEyeBVJNqWiVkuVd1S_1eCC6V1qjqildYy5b6MmesDr3_FwMT1bddyUSX8bDmZTLK_y8o74FPyzuepuVd3fai1ZLvGiW6VhJhI6tOdx21mupKdbzkTJwcXa3JOfcKT_j-LFQGWO2Z6HI7N_pQ6a7qcEOHclfv-I43TbMZDrvdvupJ16LiVc81NrXcibKSfdNUdSn7jTkILhrelKLcCVE1hdxR3QuN2FX7lpclqzmNaGxh7WUsfDhvTIwzHcqqa_bdxqIkG5crRoiPo4EJka-ccMhZWzmfI6u5NTHFjzrJJLtcTg9pzWf4A4N7H6mHSZowRtKL9x8vm9yCludXq0LVl8djZjMHe_iPbmUw97_tFPxfpNJyZMY5n5SnO8nLQfwTAAD__7__afo">