https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119364
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Looking through the failures, the first difference on group1/directive_1.cob is due to genapi.cc (stash_exceptions) doing static void stash_exceptions( const cbl_enabled_exceptions_array_t *enabled ) { // We need to create a static array of bytes size_t narg = enabled->nbytes(); unsigned char *p = (unsigned char *)(enabled->ecs); and then if nothing has changed attempts to just push the bytes into the target's initializer. This is completely wrong. nbytes is: struct cbl_enabled_exceptions_array_t { size_t nec; cbl_enabled_exception_t *ecs; ... size_t nbytes() const { return nec * sizeof(ecs[0]); } }; where struct cbl_enabled_exception_t { bool enabled, location; ec_type_t ec; size_t file; ... }; This can work fine on the library side, but on the compiler side, it computes nec times size of the host cbl_enabled_exception_t and then stores it byte by byte into the target. E.g. for i686-linux host x86_64-linux target cobol1 the above structure is 12 bytes long, 2 single bytes, 2 bytes of padding (those definitely should be never streamed, they can contain random garbage), 4 bytes ec and 4 bytes file. While on the target it is 16 bytes long, 2 single bytes, 2 bytes of padding, 4 bytes ec, 8 bytes file. And there could be different endianity, or e.g. cross from Darwin where bool is 4 bytes long to x86_64-linux would also do nightmare. What needs to happen is that the compiler constructs a target RECORD_TYPE, with 2x BOOL, UINT and SIZE_T member types (ideally just once) and then stores it field by field using native_encode_wide_int or native_encode_expr to the corresponding locations.