[clang] [Clang] Fix __builtin_dynamic_object_size off by 4 (PR #111015)

Jan Hendrik Farr via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 3 13:08:10 PDT 2024


Cydox wrote:

I'm gonna write a better explanation with some drawings of my arguments in a bit, but to start of with, clang's answer is inconsistent.

If you rewrite the reproducer in the issue to this version without the `__attribute__((counted_by(a_count)))`, and compile with `-O2`, clang says that the size is now 40 instead of 36:

```C
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int counter;
} atomic_t;

typedef struct refcount_struct {
    atomic_t refs;
} refcount_t;

struct callback_head {
    struct callback_head *next;
    void (*func)(struct callback_head *head);
} __attribute__((aligned(sizeof(void *))));
#define rcu_head callback_head

typedef struct {
    uid_t val;
} kuid_t;

typedef struct {
    gid_t val;
} kgid_t;

struct posix_acl_entry {
    short e_tag;
    unsigned short e_perm;
    union {
        kuid_t e_uid;
        kgid_t e_gid;
    };
};

struct posix_acl {
    refcount_t a_refcount;
    struct rcu_head a_rcu;
    unsigned int a_count;
    struct posix_acl_entry a_entries[];
};

int main() {
    unsigned int count = 1;
    struct posix_acl *acl;

    acl = malloc(sizeof(struct posix_acl) +
                 sizeof(struct posix_acl_entry) * count);
    acl->a_count = count;

    acl->a_entries[0].e_tag = 0x1;


    printf("%zu\n", __builtin_dynamic_object_size(acl, 0));
    printf("%zu\n", __builtin_dynamic_object_size(acl->a_entries, 0));
    return 0;
}
```

```
$ clang -O2 test.c
$ ./a.out
40
```

Compiling the original reproducer in #111009 (only change is the counted_by attribute) you get this:

```
$ clang -O2 test.c
$ ./a.out
36
```


https://github.com/llvm/llvm-project/pull/111015


More information about the cfe-commits mailing list