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

    <tr>
        <th>Summary</th>
        <td>
            Clang adds "noundef" annotation to char arguments
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

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

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

<pre>
    I think the way clang translates the following code to LLVM IR is incorrect:
```C
char id(char c) {
    return c;
}

void my_memcpy(char *src, char *dst, int n) {
    for (int i = 0; i < n; i++) {
        dst[i] = id(src[i]);
    }
}
```
The resulting IR defines `id` as `@id(i8 noundef signext %0)`. The `noundef` is what I am concerned by. This translation means calling my_memcpy as follows leads to UB, since some of the bytes being copied here *are* undef or poison (namely, they are padding):
```C
struct S {
    uint8_t f1;
    uint16_t f2;
};

void testcase() {
    struct S s, s_copy;
    s.f1 = 0;
    s.f2 = 0;
    my_memcpy(&s, &s_copy, sizeof(struct S));
}
```
If I understand the C standard correctly, this program (running `testcase`) is entirely well-defined. In particular, C17 6.2.6.1 ยง5 says (emphasis mine)
>  Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression **that does not have character type**, the behavior is undefined. 

But we are using a character type here. The standard also explicitly says in 6.2.6.2 that `char` types have no padding bits. So I don't think there is any room here for UB to arise when copying arbitrary data (including uninitialized memory) at `char` type. Therefore clang should not add `noundef` to character type variables.

Furthermore, I am not entirely sure what the status of [this proposal](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2218.htm) is, but if it has been accepted, then I am not sure that adding `noundef` to any other integer type is correct, either. That proposal states explicitly
> None of the integral types have extraordinary values.

And at least for C++, https://eel.is/c++draft/basic.fundamental#4 has a note on padding in integer types stating
> Padding bits have unspecified value, but cannot cause traps[.](https://eel.is/c++draft/basic.fundamental#4.sentence-4)

So, at least for C++, I cannot see a justification for why clang adds `noundef` to all integer types. For non-character integer types in C, the standard is not clear enough for me to be sure either way.

Cc @aqjune @nunoplopes 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVVk2T4jYQ_TXmohoXiM85cBiYUDWpTSq1m811S5ZlrImQiCQPS359XkvYwMzuIRRlhN3qfv36dcuVq8_rFxZbbf_GVbGTODNphN2z6IUNRkQV0oPGGeNOGg-kqxWLjn369Ndv7OUz04FpK533SsZi-lSMn4vxU7EY5-82_5et8EzXBV-llSz4IyuWm_yQ4eNV7LzFg-nlZrF8vizS9c3pmh3O3w7qII_n3k_Bn4KHsy3r_9Yh0l9tI7MfgjSObFb0ULNi-szGCJeWW1jTsuCb9H23kT7keb7Rxfw5bU3JUPB8D1sG6GR9hT8sekry3z9BqlehM5FIBY-1arQF27CA78WYibQuZuMUSq-YdZ2FFQt6b9X3iFTmY4q7GJeM3GFxMaHtqMupFZG9MHFA0axU3qqaVWcyxsO-wNpZdlBYMymMITADzQQhFz4wo0QdqO5fN0RwQM0VC-6gmGuSQqozaaVSWSNHjVit8oqKIrzClWX0qMHR6YCoyMqKgzJncggXiAf7o6hr-EiE_kRNIfpORvblvkgd6rr6FlkzuasE3Z4s6D6_E9ewvuoLCUQpAsCuPkhgiBlS-t-Q4vkuTiibySCqu9v8B7dvpVzwRXJKv9lvIvhf5RrS2CUwEXIjsp_p6qVBxYlpH6KwdSoNvNFa-JpdGrXnHDo4erf3kAhC-c5aKh-cDVQsSGIkJmWj9igWOyljHrJa65K9WFTMRy07Izw53U6WbFHyclGCji0vnpZzFsQ5UAB1OLYiwNkBmymbnMH0F8a2ykehLXPVK_ChNY7oDsRMAg3MKujJupsHTLA3YbpBf5eN8XxUQJXvheg89g12YvAPGCx0soWX-1CMSANCD71D07TF5P3qO9kFnZT7hG-k9qodVE_AWvGm0hgSMiqfcGSzi7rRGjDRkD-8p1bIBN6qcNNF0JvaoAtUCfHOY2qp3O1DSYUJjsAZLTUKm8kGk7kInCWYqCN5osFAfkKGa13fbqzSMZTsi4N6aofRuYzXYwFwgFnYM_POHXJb0yz9uqGBILwOODlaZanvzwm2hzsv_JnVIoo8c6XpUqAOEtNRCwOBY6Srg_NnkthHkClPrxBJXQ6l0LrOZB0A9ruBByjvyHoDNFEZFcpbknedp5wQV1Fp0nwkj4PAQ-dVnp1ZQyJ2gdSDUd93zNEFYdLYX7UxHgONKr7D93Q6le6o7EOIdek8xtjuNcoJfoLknAz2k1m2w7V2Ep2_s5xPVmUbD7nVCFUFJeiG6azUSoFcIaU6RlVf9GSvyBPgVOZLMT8QQ7VzlDWdjGrfE4Rk-pMbTpUmC2IdnvokU_7Qy1Vg16b93dmh_ZJfD_sbeeGQ8sJ5QCIppC66L8UTeg2xcLaEmBS17Q_gLbvnVSlTEjM7mS1qLxqA3lUYJ7JskCtOErSwKfh0ljgTRA3g2UHi6Inb7ENKjY6aIaE_bpohp9DZcFRSN7ofI31xpLBEvRQdxI80gXW-KX8kif8FvaRBpHC2Psyu8zFdvzgK_TO2XnpAQWF-sNcuRICWeaSR7ant3-yQY_iBQoy5Z6dkO2yzzj5cu-qePvC57YfbMI10noYSKD1aynX7NsU_pJfGSmWxZqnR6-adHraS4X1H_PPaQVhY2c66o3EUbFSvp_Xj9FGMIkSo1tubXDjvc-GcJRpy3peJgHG074jiMOq8Wd9XZw8kXVVKh-bbGfPW_zygAV5TY-x0CBAuFvPFfD4ZtevJuOazajwRyxkQTbicNOPFcrqqheSr5epxZESlTFhDERDESK_5mPPxcjKfLPmKz0s-m9VSLBulqrrhqykyVQehTUmBaWqM_DphqLp9wEOjA4bz8FCE9Aaoev-ii63z68_CNL92dj9KeNcJ7H9Q0Mqb">