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

    <tr>
        <th>Summary</th>
        <td>
            -fsanitize=bounds missing bounds provided by __builtin_dynamic_object_size()
        </td>
    </tr>

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

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

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

<pre>
    While `-fsanitize-bounds` is able to perform run-time bounds checking on fixed-size arrays (i.e. when `__builtin_object_size(x, 1)` does not return `SIZE_MAX`), it does not perform bounds checking when `__builtin_dynamic_object_size(x, 1)` is available.

For example, the attached program produces no bounds-checker warnings for the "dynamic size" case:

```
/* Build with -Wall -O2 -fstrict-flex-arrays=3 -fsanitize=bounds -fstrict-flex-arrays=3 */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

#define noinline __attribute__((__noinline__))

volatile int zero = 0; /* used to stop optimizer from seeing constant expressions. */

#define report_size(p)      do {    \
    const size_t bdos = __builtin_dynamic_object_size(p, 1); \
    \
    if (__builtin_constant_p(bdos)) { \
        if (bdos == SIZE_MAX) { \
 printf("\n" #p " has unknowable size\n"); \
        } else { \
            printf("\n" #p " has a fixed size: %zu (%zu elements of size %zu)\n", bdos, \
                   bdos / sizeof(*(p)), sizeof(*(p))); \
        } \
    } else { \
 printf("\n" #p " has a dynamic size: %zu (%zu elements of size %zu)\n", bdos, \
               bdos / sizeof(*(p)), sizeof(*(p))); \
    } \
} while (0)

#define report_assignment(p, index, expect) \
    printf(#p "[%d] assignment: %d (should be %s)\n", index, (p)[index] = 0xFF, expect)

#define MAX_INDEX       16

struct fixed {
    unsigned long flags;
    size_t foo;
    int array[MAX_INDEX];
};

/* should emit "fixed" */
static void noinline do_fixed(struct fixed *p, int index)
{
 report_size(p->array);
    report_assignment(p->array, 0, "ok");
    report_assignment(p->array, index, "failure");
}

struct flex {
    unsigned long flags;
 size_t foo;
    int array[];
};

/* should emit "dynamic" */
static void noinline do_dynamic(unsigned char count, int index)
{
    /* malloc() is marked with __attribute__((alloc_size(1))) */
    struct flex *p = malloc(sizeof(*p) + (zero + count) * sizeof(*p->array));
    report_size(p->array);
 report_assignment(p->array, 0,      "ok");
 report_assignment(p->array, index,  "failure");
 free(p);
}

/* should emit "unknowable" */
static void noinline do_unknown(struct flex *p, int index)
{
    report_size(p->array);
 report_assignment(p->array, 0,      "ignored");
 report_assignment(p->array, index,  "ignored");
}

int main(int argc, char *argv[])
{
        int a;
        struct fixed f;
 int b;
        struct flex *p;
        int index = MAX_INDEX + zero;

        a = b = argc; /* wrap "f" with an extra int to catch overflow writes */
        do_fixed(&f, index + a - b);

 do_dynamic(index, index);

        p = malloc(100);
 do_unknown(p, index);
        free(p);

        return 0;
}
```

```
$ gcc -Wall -O2 -fstrict-flex-arrays=3 -fsanitize=bounds -fstrict-flex-arrays=3 -o bounds bounds.c
$ ./bounds

p->array has a fixed size: 64 (16 elements of size 4)
p->array[0] assignment: 255 (should be ok)
bounds.c:43:5: runtime error: index 16 out of bounds for type 'int[16]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior bounds.c:43:5 in 
p->array[16] assignment: 255 (should be failure)

p->array has a dynamic size: 64 (16 elements of size 4)
p->array[0] assignment: 255 (should be ok)
p->array[16] assignment: 255 (should be failure)

p->array has unknowable size
p->array[0] assignment: 255 (should be ignored)
p->array[16] assignment: 255 (should be ignored)
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0WE-P4joS_zTmUgoKDuHPgQM0g_QOsyvt6OnN7gU5sUP8OrEj2wG6P_3KdhISOvT0zJtGCJK4yvWrql-V7RCt-UkwtkHxDmHMNREJURRhjOL9hNQml2rzzJieJJK-bP7KecEALcIg00Rww19ZkMhaUI0WIXANJCkYGAkVU5lUJahaBIaXDLwUpDlLn7k4gRSQ8SujgeavDIhS5EUDwis-ZVO45ExYK8djUvPCcHGUyd8sNUcrjPDqivATzBBeW6tUMg1CGlDM1Mrpffvjf1-OX7ff0SK0QvgJuLnJtdjuIb21Sl8EKXn6nnXr85nwwjo-ReEehVv_e5AK2JWUVcGsvMkZEGNImjMKlZInRUr7T-vUwWrQBA4NU3AhSnBx0pBJ5ZQRxg0c8DgwpEQzFG37Vq3H_utv8QHhLexqXlC4cJND8BcpCgj-jSHItFE8NUFWsGvgM4CifQS33KJo3wTpoTDCzkhjLeIiLWrKAEVP2lAuzDRH0ZdHw_KdUcXF6eFwSYpCpv3hVoiyjAsGQnJR2IvjkRijeFIbdjwivEJ4dTy2o_bJ2n57c5xlQYxlORcGXpmSgKI9hCjaQRPNWjNqOa6NrEBWhpf8lSnIlCxBM2aplEqhDREG2LVSTGsuhZ4OY3UHWLFKqo5iFcJrcB8qAS139grFT17J3jgDjghHAwmV2qH8EXOrjrnWm_58gxuegQtTO1nrzbFCeGWN-ag5YAPFm3ILyaLqqvGNSqW4MJnLCkbxk7CkRjiqLNkhJxpq8SzkxTUV54KXGXPAObHcAys0GwdmPz80SHxX8taiLSAcv9bgFOwFK1jJhNEgMyfixy2eFtkT-AA9jQNoPj48-OAmkR7Qtsl707EejTx2fZjQ8Vh8IACDLvM5Ifit7g9ctzcXv0jhVXhX2m-qza9-1p22OLigzPV3dq1Yahxl-8Z68fNBc-tmTFG8h95sPmzUgtC5rAsKiQuUHsaps9Z6GO_8o3jvu871cBiAGffm6_b78Y9_7b98b8I7W_TltFF1ahpeo-Xu5kwt3OJPoZDiBFlBThpFvfGmvWRSDh7bxuhWABTvOtMo3ndCaNm77q9DTSxYyY2NnYPkGXhrjNoQw1M4S05vXZzKYyO8GrqDt03aTBvMNkado3edNUDRF4_ecenm1ignetJPEPpUYfncNaGfUe9lG2eEF7Vid_PYwI1krmDXn0jcB7L2K8lq2sJH09WJrzqwaU4UpLK2oXk_ZbaqPQi_0Lt6W9u9VknUM2u2MiNLu5NuUz3resYAsWN2P7J4W7lq62z1e0_l1e3iv_K7AbxrnXDzDjrVkF3jDHmfiB9koW_6Y1T8CR4-JiJkirX7kEfsHKfJbcX-KFO8huiVdpuVD9DkM2LKT0Iq15j-SWDHZ7mLofWuJNw67-vzlFp9VykIb4k6nZtyHfW-q-sBz_oEd10yuw1b6eShdBf4e4EuC65QbuuNLQZbFXcdpFUjTjxxv8632yb6oohbPzNLE1fORAC7GkWcMSMhJSbNQZ6Zygp5gYvihuk3lez3yN3qgPAi61Lh4BEIIBmkwOsOelSXuY5q4w7dNYpZGA4oMmBzNTpfO9NogQ0kmuNsOMKdu0Pe-MlvDqc0_e3nvaA9qTZ_0_Rmb4rwoXkb0AN2q5HRHfZiblvrbPF2YznvSN8rs3gXvt1r4TgebrVsW2x0O5jRdh6haBtbBVUL91aCKSWVfeD5MluArI0F0PjoDt8vld27LbkwKN7NFq4al37yb39-_br9z3_tDH8KvxujO5aTM5fqWxNUN3_djgZJMwxvgAEXMOKvs_gjh7s2vn439Pd7-88O_ic5cn8s_DWcXYf-ZbD3M9zV4IRuIrqO1mTCNrPFchmu18vVepJvZlG8xtl6Qcg8pOmKzhmNsvkyJGmYzNI4m_ANDnEUYozxLIzC9XQezzMaU4LTNEoZDdE8ZCXhxbQozuVUqtOEa12zzSJc48WkIAkrdPNOT7ALuMHmpZ7aWJ0gqU8azcOCa6NvsxhuCrYZ6wgl15qLU1sZlZJnThmF5OWHrx0QXk9qVWxyYyqNIr9zOJy4yetkmsoS4YMF0PwFlZJ_u-POwcHWCB-cW_8PAAD__9STBCc">