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.

Reply via email to