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

    <tr>
        <th>Summary</th>
        <td>
            provide "element_count" attribute to give more context to __builtin_dynamic_object_size() and -fsanitize=bounds
        </td>
    </tr>

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

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

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

<pre>
    Frequently a structure containing a flexible array member will also contain a member where the count of array elements is stored. For example:

```
struct foo {
    ...
    unsigned int count;
    ...
    int data[];
};

struct foo *allocate_foo(unsigned int how_many)
{
    struct foo *p;

    p = malloc(sizeof(*p) + how_many * sizeof(*byte_array));
    p->count = how_many;

    return p;
}
```

While `__builtin_dynamic_object_size(p->data, 1)` will know the size within `allocate_foo()` due to `malloc`'s `__alloc_size` hinting, this information is immediately lost on return. However, the information _is_ still available in `p->count`, but the compiler has no way to know about it.

Please provide a struct member attribute `element_count` that can be used to associate the size of a flexible array to another struct member. For example:

```
struct foo {
    ...
    unsigned int count;
 ...
    int data[] __attribute__((__element_count__(count)));
};
```

Now any later examination of the size of `data` can be calculated. For example, this equality will hold true:

```
 __builtin_dynamic_object_size(p->data) == p->count * sizeof(*p->data)
```

and `-fsanitize-bounds` can examine this as well, to trap:

```
    p->data[index] = ...; /* traps when index < 0, or index >= p->count */
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8VcFu4zgM_RrlQjSw5cZJDj5M2wn2tNjbHg3ZpmPtyFJGoppmvn5BOUnjdHaKvQxQuLFM8fE98kkqBL23iJVYPYnVy0JFGpyvviGGReO6U7Xz-D2iJXMCBYF8bCl6hNZZUtpquwcFvcE33RgE5b06wYhjgx6O2hhQJrhLMKjrpwE9Ag2cJ1oC15-3osERLQXQAQI5j90Sds4DvqnxYFAUX0T2IrLLs8zOf-l1qg5650Csn6Y1AIDlcvn-Em0i3IG2NKGL4r9iOaRTpCZtrnFiffP7A7L8ooxxrSKse-eE3MwQB3esR2VPQm4vyW7Q53kOdygccQBRvMCYIITcBP0DXS_kJoXLLQj5dMXgHHAb0ZwI6yQ0w8vtjPnhQRRfp3YwxLXQjzV4pOgtHGaC_Kwh0_PvQRsEUWZ13URtSNu6O1k16rZ2zT_YUs01CrlJFSS95TPkXF-ZTVP0zbpjGheOhKOmQVvOeKf0eUsXEcjx97NOZSbkOkwlpJUJscxg0Ja03TMgDTqAtr3zoyLtLI-gHkfstCI0JzAuEDh7Zr-EP9wRX9FPW3G2s9ahhkBp_l-VNoq9MVX8rnKq6hmaSGcjjAdt0MOgAlgHR3ViEom5alwk0LS8lfUvgyogHLx71R1ezXmxmCLyuomUlD_bqr4AAw2KoFUWGoQYsGMoFYJrmey70uzLe3dzpHU0oJ8j_k6j_sKlUNdX6nWdhmJT1zMB0vKUcbLBjRNm3v7ZNP_J_bAnMIpwoqvt1HXXz4QTZZaqKrOL0K0ybeR9d4faZfjwe1RG02ma-cGZDsjHT7SE_-GqLTubzX3r9bsz4jb8FzIo2zHDhz4oq0n_wIfGRduFC91JGJyIqQBHNCYRdUBeHT7hdDmOzm3VtsM37i3Xzr0vnkDIHZfOyQLfJxZSFIjiGZKxnL-ufP3ImbfPoRddVXTbYqsWWOXlep1n-WMpF0OVF-sswy5flY_NFvttueqlzBvcyNUK87Zd6EpmssiklDIvslW5bMtss3mUqs3aps_zXjxmOCptlsa8jkvn9wsdQsSqzLZyszCqQRPSBSylxSOkj0JKvo99xXsemrgP4jEzOlB4z0KaDFaXE0BIOfe5lDenADnY61eE0Z1vb3wjXvxsfHhquNnvnRbFy9TrRfSmGogOgdvJ_djtNQ2xWbZuFHLHdZ7_PRy846xC7hK7IOQusf83AAD__wHeoCE">