-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Hi there, great library.
I have briefly looked into the code, and I have stumbled some potential problem with emsMem struct.
ems struct is declared as :
struct emsMem {
int32_t level;
uint8_t tree[1];
};
but tree is not an array of one byte, it is actually a slice of a bigger array allocated in emsMem_new:
struct emsMem *self = (struct emsMem *) malloc(sizeof(struct emsMem) + sizeof(uint8_t) * (size * 2 - 2));
yet, what GCC see in other functions is basically access to tree as uint8_t(*)[1], for example
self->tree[index] == BUDDY_UNUSED
where index can be any number.
for GCC, this is undefined behavior if index != 0 (and it is, for most cases ) , even though tree is a valid allocated block, but tree is declared as uint8_t[1].
GCC is known to use optimizations that rely on undefined behavior. an improvement is to turn tree from uint8_t[1] to uint8_t*. for GCC, it cannot determine if tree[index] is undefined behavior or not at compile time, thus minimizing the possibility of undefined-behavior based optimizations.