<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/76406>76406</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
clang 18 has forgotten how to compute `strnlen` of a stack buffer
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ecatmur
</td>
</tr>
</table>
<pre>
```c++
#include <string.h>
int f() {
char const s[] = "abcdefg";
return strnlen(s, 8);
}
int g() { return strnlen("abcdefg", 8); }
```
clang 15 through 17 (at -O) optimize both `f` and `g` to `mov eax, 7; ret`.
clang 18 trunk 68f832f56da1af0e5fc77003f640648ec7d901ad continues to optimize `g` but has forgotten how to optimize `f`:
```
f: # @f
push rax
movabs rax, 29104508263162465
mov qword ptr [rsp], rax
mov rdi, rsp
mov esi, 8
call strnlen@PLT
pop rcx
ret
```
However, if the buffer is expanded to > 64 bytes, it remembers again:
```
int f() {
char const s[65] = "abcdefg"; // this is fine
return strnlen(s, 8); // mov eax, 7; ret
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMVN1urDYQfprhZpSVscHABRdJ9qx6Uam96AsYMwb3AKa2SXL69JXZzW433SPVsoRhfr6Z-fyhQrDDQtRC-QLlMVNbHJ1vSas4bz7rXP-jBcnOWwN_SZsdgT0DF3bR09YTgngN0dtlOIwgvp3NdologNfAG4TqEoOIqEflUbslRAxnUARxROBcdbonMwDnIP4V4ClufsEQ_TLRArwOwF8xJb66QXW8oQ431P_G3sPc8uA1xbXb86ue1DJgXmIcvduGEfMKgdcq4tNvCcWt0c72b8LOxRFBMgOSoVr6dB7SObp0nN0bkvpIkFXC8xRBssMdSI3Rb8t3lLWpBTel7FWuDKPS6KpiTBhZMFnUpKu-Ybnq0xijXTYKCeRaySdwt0UcVUDj_OBipAVH9_7VM5UL4vlh7wbEMwIXCAUzN0LSWrcw7uSoj4thdm-qC-cv_BV5k7OiZDWXIpe8kOV9fBpHWn-9O9_jGj1C-eLDCuUxRd-l3R19b3dDWB8nomDPdN5ZtZqmK_sF-_3XP7604dZzdv1xb0j0PBrJL-6d3sgnKGswjoTdZgx5tAHpY1VLT_3OuPiGssDuR6T9utqInmaaO_IB1aDs8rOhPxbOF9XI8me6QeAn4CeMow2pKGMX-p9a-gx9dFXvZXYtOetb0TeiURm1ecWEzJumkdnY1trI2pRlxTstc1kLzoQkVumqN4JKldmWMy5yzmXeFFLIQ1cL6rq-73jVy7zUUDCalZ0O0_Q2H5wfMhvCRm2VRJBNqqMp7H8tznf5pPbLY-bb5P_UbUOAgk02xHDLEG2cqL2q7aE4tJvXLe7a-ByTZOgMKgxR6e8XwrPNT-0Y4xoSkfvgBhvHrTtoNwM_JczL42n17k_SEfhpbyEAP-1d_BMAAP__EZqMKw">