https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116605

            Bug ID: 116605
           Summary: __builtin_object_size and
                    __builtin_dynamic_object_size in mode 1 fall back to
                    mode 0 for rows of multidimensional arrays
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gustavo at embeddedor dot com
  Target Milestone: ---

__builtin_object_size() and __builtin_dynamic_object_size() in mode 1 fail to
correctly determine the size of multidimensional arrays when the addresses of
their rows are passed as arguments. In this scenario, the built-in functions
fall back to mode 0. See the example code below[1].

#include <stdio.h>

#define expect(p, _v) do { \
    size_t v = _v; \
    if (p == v) \
        printf("ok:  %s == %zu\n", #p, p); \
    else \
        printf("WAT: %s == %zu (expected %zu)\n", #p, p, v); \
} while (0);

const char array[][10] =
{
    [0] = "0123456789",
    [1] = "0123456789",
    [2] = "0123456789",
    [3] = "0123456789",
    [4] = "0123456789"
};

int main(void) {

    /* the whole object: array */
    printf("\nWhole object: sizeof(array) = %zu\n", sizeof(array));
    expect(sizeof(array), 50);
    expect(__builtin_object_size(array, 1), 50);
    expect(__builtin_object_size(array, 0), 50);
    expect(__builtin_dynamic_object_size(array, 1), 50);
    expect(__builtin_dynamic_object_size(array, 0), 50);

    /* first row: *array */
    printf("\nFirst row: sizeof(*array) = %zu\n", sizeof(*array));
    expect(sizeof(*array), 10);
    expect(__builtin_object_size(*array, 1), 10);
    expect(__builtin_object_size(*array, 0), 50);
    expect(__builtin_dynamic_object_size(*array, 1), 10);
    expect(__builtin_dynamic_object_size(*array, 0), 50);

    /* second row: array[1] */
    printf("\nSecond row: sizeof(array[1]) = %zu\n", sizeof(array[1]));
    expect(sizeof(array[1]), 10);
    expect(__builtin_object_size(array[1], 1), 10);
    expect(__builtin_object_size(array[1], 0), 40);
    expect(__builtin_dynamic_object_size(array[1], 1), 10);
    expect(__builtin_dynamic_object_size(array[1], 0), 40);

    return 0;
}

Clang (trunk) correctly resolves the sizes:

Whole object: sizeof(array) = 50
ok:  sizeof(array) == 50
ok:  __builtin_object_size(array, 1) == 50
ok:  __builtin_object_size(array, 0) == 50
ok:  __builtin_dynamic_object_size(array, 1) == 50
ok:  __builtin_dynamic_object_size(array, 0) == 50

First row: sizeof(*array) = 10
ok:  sizeof(*array) == 10
ok:  __builtin_object_size(*array, 1) == 10
ok:  __builtin_object_size(*array, 0) == 50
ok:  __builtin_dynamic_object_size(*array, 1) == 10
ok:  __builtin_dynamic_object_size(*array, 0) == 50

Second row: sizeof(array[1]) = 10
ok:  sizeof(array[1]) == 10
ok:  __builtin_object_size(array[1], 1) == 10
ok:  __builtin_object_size(array[1], 0) == 40
ok:  __builtin_dynamic_object_size(array[1], 1) == 10
ok:  __builtin_dynamic_object_size(array[1], 0) == 40

However, GCC (trunk) produces some incorrect results:

Whole object: sizeof(array) = 50
ok:  sizeof(array) == 50
ok:  __builtin_object_size(array, 1) == 50
ok:  __builtin_object_size(array, 0) == 50
ok:  __builtin_dynamic_object_size(array, 1) == 50
ok:  __builtin_dynamic_object_size(array, 0) == 50

First row: sizeof(*array) = 10
ok:  sizeof(*array) == 10
WAT: __builtin_object_size(*array, 1) == 50 (expected 10)
ok:  __builtin_object_size(*array, 0) == 50
WAT: __builtin_dynamic_object_size(*array, 1) == 50 (expected 10)
ok:  __builtin_dynamic_object_size(*array, 0) == 50

Second row: sizeof(array[1]) = 10
ok:  sizeof(array[1]) == 10
WAT: __builtin_object_size(array[1], 1) == 40 (expected 10)
ok:  __builtin_object_size(array[1], 0) == 40
WAT: __builtin_dynamic_object_size(array[1], 1) == 40 (expected 10)
ok:  __builtin_dynamic_object_size(array[1], 0) == 40

[1] https://godbolt.org/z/afWMKKoGo
  • [Bug c/116605] New: __builtin_o... gustavo at embeddedor dot com via Gcc-bugs

Reply via email to