https://bugs.openldap.org/show_bug.cgi?id=9916
--- Comment #15 from Howard Chu hyc@openldap.org --- (In reply to jrtc27 from comment #14)
#define mp_lower mp_pb.pb.pb_lower #define mp_upper mp_pb.pb.pb_upper #define mp_pages mp_pb.pb_pages union { struct { indx_t pb_lower; /**< lower bound of free space */ indx_t pb_upper; /**< upper bound of free space */ } pb; uint32_t pb_pages; /**< number of overflow pages */ } mp_pb;
That alone means the struct must be uint32_t aligned otherwise you have UB. It is perfectly legal therefore for GCC to optimise the two loads to a single wider load. In fact, struct MDB_page even has a pointer in it inside mp_p so it needs to be pointer-aligned, i.e. 64-bit-aligned, to not have UB.
The C spec only requires that the alignment of a pointer match the object being referenced. The object being referenced here is a 2-byte integer. GCC is broken.