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

    <tr>
        <th>Summary</th>
        <td>
            __builtin_calloc has incorrect semantics on wraparound
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            c2x,
            miscompilation,
            llvm:optimizations
      </td>
    </tr>

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

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

<pre>
    When passing values to `calloc` such that the result of `nmemb * size` cannot be represented, the result of the call is null. However, our builtin does not exhibit this behavior, which is especially problematic given that we automatically replace calls to `calloc()` with a call to `__builtin_calloc()`, so even if the platform c standard library implements the correct behavior, the user isn't protected (unless they pass `-fno-builtin`).

Consider:
```
typedef char (*arrayptr)[0x700000000000000];

int main(void) {  
  arrayptr p, q;

  p = __builtin_calloc(32, sizeof *p);
  if (!p) return 0;
  q = p + 32;
  return q - p;
}
```
this returns `-4` instead of `0`: https://gcc.godbolt.org/z/GoeGPrv3x

Note that WG14 adopted https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2810.pdf into C2x to clarify the intent of the standard. While this was adopted into C2x, I do not think the behavior here should be tied to a specific standard version unless there is a very compelling reason to do so.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJxtVU1z4jgQ_TXm0oXLliG2Dz5AUpPZy9beckzJkow1IyRHkiHk12-3DJOEGspYqPW69fqT3slL9zIqCxMPQdsDnLiZVYDoIHsoBDfGCfwBYRYjxJFHfCnwKswmghsIZI_q2EPGdhD0hyKw4Na6CD0BJ8QqG5XM2OOdLu3oBtAB7GxMDj_dWZ2UJ6ibPfSzNlFbkA4ZkUX1PupeEwdU6dXIT9ol9HnUyA-FKkxKaDR6gcm73qgjj1rAQZ_Qx8T_rIDP0SV5wiFHw8VC5c5x1mSsJY_OOo7AF7YL4vX1yu71Dkt0ggNFF-rFSbQfB-ePICBEbiX3EozuPfcX0McJSWKEwhIP570S8ZtzJJ-D8uifzVgdybOIICUx6s1sjQpJ-ZKSSOTWg3XrK79Eqc2z4ikrdsv70dmgJca5ugoIszxpGy-TkmoAMXIPybEd955fpujJx-2-eK-Lb59s-5RV-693aBvhyPF61pycxuy3kNV7gOUU4GYQJnLx7U4bYIKseoK_RLliKcJYalR-bDcRpZs2UMgT45LkmNs4ewvFF8BbMozm2R7Q1ufBFfsGa-T0h0799PcQUQUuGkvEN1Qm2oaouLw2RkJXOxhjnALFmv3A5yBEfnCydybmzh9Q8oHfZ6ee__On6v1rFP7FNC9F-_JcboBLN1HSv9s7n8-5m5RdhyivBn9FUeISBGMEOJSbBYdv6UTAxbKmLPJJDkgZ6_mRvVNZC8O9Hi6p4FCORXlr01vZ5vAyaqOWBjzz8IfTzQzl5h9s2NSuiLK_k_6tnGFUHq2NbjaS5kPUqIuaHFLfDvpLh-AgCNpZ-CxwVMVrOZ1csFOOkzKGZpZXPCAQ7eDFweUr1ZUPD2W7LbdVu5JdJduq5auoo1HdfUnBiG5oe2u8gBPD4mgIgBbPnk_cu9nK1exNd5dInAlznyMP3Bhzui1rbM9faAq3OgQcpvhjW2_qejV2taxr3g9DI2Vd1L1oh4Y3zcDabYuEH_qV4b0yocMeyxgTFM9U7rgcdSCXNc4SjMqnPN1c7TAN-qg_0mGg0-3TSnesYKxoqrKsSla2eSN5salFtZVtU2-abbYp0F1tcjJCxbPyXXKhnw8BD40OMXwe0l_EwSqV6KF9nKOj8x0OB2f3GEyM3Cq53CV__wdNQAlb">