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.