https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92123

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Yeah, I think on x86_64-linux it works by pure accident.
The type used on the C side is:
typedef struct CFI_cdesc_t
 {
    void *base_addr;
    size_t elem_len;
    int version;
    CFI_rank_t rank;
    CFI_attribute_t attribute;
    CFI_type_t type;
    CFI_dim_t dim[];
 }
CFI_cdesc_t;

where void * and size_t are 64-bit on LP64 and 32-bit on ILP32,
CFI_rank_t/CFI_attribute_t are 8-bit and CFI_type_t is 16-bit, while for
    integer(c_int), allocatable, intent(out) :: dat(..)
    select rank (dat)
      rank (0)
      allocate( dat )
      dat = 42
    end select
    return
seems to assume dat type is a structure containing pointer sized data,
array index offset, and dtype, which has size_t elem_len, int version, 8-bit
rank, type and 16-bit attribute, so the Fortran FE assumption is there is extra
64-bit (or 32-bit) offset and type/attribute are swapped and have different
types.
Which means from the C side, rank is at offset 20 bytes into the structure for
LP64 and 12 bytes in ILP32, while the Fortran emitted code when it reads
dat->dtype.rank reads it from offset 28 bytes into the structure or for ILP32
16 bytes.

Reply via email to