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

    <tr>
        <th>Summary</th>
        <td>
            builtin causing strange errno corruption for function named reallocarray
        </td>
    </tr>

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

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

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

<pre>
    If I have one program composed of 2 C source files, _reallocarray_test.c_ and _reallocarray.c_, with the following contents:

_reallocarray_test.c_:
```c
#include <errno.h>
#include <stdio.h>

void *reallocarray(void *optr, size_t nmemb, size_t size);

int
main(void)
{
        errno = 0;

        reallocarray(0, 0, 0);
        printf("1st errno val after  return: %d\n", errno);
        printf("2nd errno val after  return: %d\n", errno);
        return 0;
}
```
_reallocarray.c_:
```c
#include <errno.h>
#include <stdio.h>

void *
reallocarray(void *optr, size_t nmemb, size_t size)
{
        errno = ENOMEM;
        printf("    errno val before return: %d\n", errno);
        return NULL;
}
```
And if I compile and run it with builtins off and then builtins on, the program's output is different:
```console
$ clang -O2 -fno-builtin -o builtin_off reallocarray_test.c reallocarray.c
$ ./builtin_off
    errno val before return: 1
1st errno val after  return: 1
2nd errno val after  return: 1
```
```console
$ clang -O2 -o builtin_on reallocarray_test.c reallocarray.c
$ ./builtin_on 
    errno val before return: 1
1st errno val after  return: 0
2nd errno val after  return: 1
```
Here's a diff:
```diff
--- /tmp/builtin_off.txt        2025-07-16 14:18:18.140908085 +0000
+++ /tmp/builtin_on.txt 2025-07-16 14:18:22.365877065 +0000
@@ -1,3 +1,3 @@
     errno val before return: 1
-1st errno val after  return: 1
+1st errno val after  return: 0
 2nd errno val after  return: 1
```
Strangely, when builtins are enabled, the first read of errno is 0, while the 2nd read is 1, even though at the C level there is no write to errno between these 2 reads. The compiled program isn't actually calling the builtin reallocarray (nor should it), as evidenced by looking at the program's output and disassembling the program.

I can confirm this behavior on the following versions of clang:
```text
clang version 22.0.0git (https://github.com/llvm/llvm-project.git 968d38d1d7d9de2d5717457876bba2663b36f620)
```
```text
clang version 20.1.7
```

This bug is very finnicky. If I join the source files and create a single-file program, it no longer happens. If I comment out `errno = 0;` from _reallocarray_test.c_'s `main()`, it won't happen either.


</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0Vk2P4ygQ_TXkUoqFcfx1yCGdntaONB-HnT23sCnbzGCIAKcn--tXYKcnnc2ot3d2IyuJqeIV1OMVxZ2TvUbckvyO5PcrPvnB2G0_ya9crxojTtv3HbyHgR8RjEY4WNNbPkJrxoNxKMB0wGAPzky2ReikQkfYHh4tcqVMy63lp0ePziftI3AtXlqS9jF4P0k_gB8QOqOUeZK6h9Zoj9o7ku0IDc9NxMVa0PlpwwvLpG7VJBBItkdrtUkGkr37m8l5IX-Y6O5opADCdpdxCKvOw-bgbVirk3_iowc94thcvIcfwmqS3c1oUntCdyOXesEIRroj5Wyv48KAZPdAn-cQWl8FpyHC-esZvD5YqX1HWEUYS52HGezIFfDOowWw6CerSbYDwnJB8r0mjAWY6PkzKKbFr0DNns_7Ke8vqblm8H8ij9Bf5O8mRe8-ff747uPNnAHARc4a7IzFt-fs0x8fPvwsbTstQAYRBs1JhVFFdtIg_SycZpLKS-3AdF00-gH1xagOkYO6FvESVjowkz9MHqQDIbsOLWp_zYfRziiMqd9Aq7juYf2ZwbrTZr2gw9qcAz2G6Dc0Ci9ZX-ASwh4uJhK6eyWRKaG7V456cHnlCKdXuX19sxf70_9yexr-k-3Rt2_vN7QY2eaR5SuC4xDdrddrIOzBj4eXnCT-u4flwyjL17RcpwWkG5Lt0ip-JemG1rSiVQ6E3VFKY07Z3fzcQNUR9CYaY0lW5FVZ0uIF2oaSDYV1Stg-C-PLnzi85PW1xK7_wcEJyK_nH95IwO_ect2jOsVb7oUsuUVAzRuF4qzPTlrnw4GK1-ocRrq5_j8NQfrBKywh-kgHaSwqR9TgBzP1A3Afffag8Igq_LcYHLWBJys9gjcLcIP-CeNEdAgsQroEvgx4LjTi-baXThNWeuCtn7hSJ2i5UuGWDrHOpeBSCEBYpY0FN5hJCZA-1Dy2B-4Aj1KgblFAcwJlzLeAsyz7RoEK9UxIx53DsXmOuTgmc_F_Dy3XoWPopB3BD9JBgwM_SmPB6KvG4ojWSROr5azzK1V4_B5u7rkELM7AWEIT2ksfNjZ4f4h9CXsg7KGXfpiapDUjYQ9KHc8_64M1X7H1SZhVF5XIKpGKUtQCmcjLtNzkZVUWTcNZUWRNVnQFo8sNdKtC3V4XTdKkvJ5Cd19iDqY-UH9Ee4JOai3bb6cEYj_31cg5L5d9W8x1a5F7BA5O6l7hOlh-8LIPl442oIzu0cLADwfUbgFtzTii9oE5IAW96nAKCp014-3OMDJOCrr0SyENBV3CPZn58M3BAGU41AvzK7HNRJ3VfIXbtMxZURZ1Wq-GbVUy3lVMsEK0gtZVJtqMNRsh0iotaZOu5DZUIVqmRbrZpHmdpHVd5pSXvK4zXuQ52VAcuVRJIDMxtl9J5ybcpps6pdVK8QaVi30zYxqfIFrDNZ_fr-w2noBm6h3ZUCWddz9gvPQKt2fVtHwKmQY3V4pFnK2xdjr4QHFnLHSTbuOL5iOKF0pbTVZt33YiCXuIi3WEPSy7OW7ZXwEAAP__XYPEIA">