Closed kaetemi closed 2 years ago
Thanks, this looks like it could be the actual issue behind #44 indeed. Very subtle, nice detective work! This looks like a low-risk change to me and solves a reported issue, so I'll merge it without verifying manually myself.
CC @timblechmann
Now the remaining question is, can whatever that ends up stored inside this object_rep allocation be an object that has higher alignment requirements? If so, then void* allocate(std::size_t size)
in object_rep needs to be changed to include the alignment, and any higher alignment requirements can just be aligned at runtime.
That might in theory be a problem I think. But since lua_newuserdata should have the same issue, it is hopefully not relevant in practice. It's been a long time since I looked at the code, but maybe due to the now correct usage of aligned_storage, the compiler would even be able to detect any underalignment and it would just be a performance issue. But not sure about that.
The
object_rep
class is allocated and initialized as follows:The class also contains the following member:
The alignment guarantee of
lua_newuserdata
can be found from:This is likely 8 bytes.
The alignment of boost::aligned_storage can be found from
alignof(std::max_align_t)
.This may be either 8 or 16 bytes, depending on the platform.
When the class is aligned to 16 bytes,
movaps
may be used by the compiler, as the compiler assumes the allocation has the specified alignment.But when the allocation is only aligned to 8 bytes at the same time, this causes an alignment crash in the constructor called during placement new.
Patch applies the correct alignment guarantee of
lua_newuserdata
to the storage.