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

            Bug ID: 93524
           Summary: [ISO C Binding][F2018] CFI_allocate – elem_size
                    mishandled + sm wrongly set?
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

CFI_cdesc_t structure type has:

size_t elem_len;
  If the object is scalar, the value is the storage size in bytes of the
object;
  otherwise, the value20is the storage size in bytes of an element of the
object.


CFI_establish has:

elem_len
   If type is equal to CFI_type_struct, CFI_type_other, or a Fortran character
type
   code, elem_len  shall be greater than zero and equal to the storage size in
bytes
   of an element of the object. Otherwise, elem_len will be ignored.

(Similarly: CFI_allocate and CFI_select_part, although they only have character
and not other/struct.)


EXPECTED:

1. For establish/allocate/select_part, the elem_len is handled properly.
   (Check all three, the testcase only uses the first two.)
2. The CFI_allocate + CFI_contiguous work nice together.

Regarding 1: Is seems as if establish handles it correctly but allocate
fails if it's argument is elem_len = 0 – even if the descriptor has the
proper elem_len = 4.

Regaring 2: Currently, is_contiguous is 0 because:
      {base_addr = 0x408910, elem_len = 4, version = 1, rank = 3, attribute =
1,
       type = 1027,
       dim = {{lower_bound = -10, extent = 21, sm = 4},
              {lower_bound = 0, extent = 6, sm = 84},
              {lower_bound = 3, extent = 8, sm = 24}}}

Here, the contiguous check works fine for dim=0 as sm=4 == elem_len.
It also works for dim=1 as sm[1]=84 == sm[0]=4 * extent[0]=21 => 84 == 84
But for dim=2, sm[2]=24  !=  sm[1]=84 * extent[1]=6 => 24 != 504

That looks like a bug in allocate – but I might have also misunderstood
something in is_contiguous.

Test case; note the bounds of the second Fortran function are wrong because
PR 92189

==> hello_world.c <==
#include <stdlib.h>  // For size_t
#include <ISO_Fortran_binding.h>

void my_fortran_sub_1 (CFI_cdesc_t *dv); 
void my_fortran_sub_2 (CFI_cdesc_t *dv); 

int main ()
{
  CFI_CDESC_T (3) a;
  CFI_cdesc_t *dv = (CFI_cdesc_t *) &a;
              // dv, base_addr, attribute,            type, elem_len, rank,
extents
  CFI_establish (dv, NULL, CFI_attribute_allocatable, CFI_type_float, 0, 3,
NULL); 

  if (dv->base_addr != NULL)
    return 1;  // shall not be allocated

  CFI_index_t lower_bounds[] = {-10, 0, 3}; 
  CFI_index_t upper_bounds[] = {10, 5, 10}; 
  size_t elem_len = 0;  // only needed for strings
  if (CFI_SUCCESS != CFI_allocate (dv, lower_bounds, upper_bounds, elem_len))
    return 2;

  if (!CFI_is_contiguous (dv))
    return 2;  // allocatables shall be contiguous,unless a strided section is
used

  my_fortran_sub_1 (dv);
  my_fortran_sub_2 (dv);
  CFI_deallocate (dv);
  return 0;
}

==> hello_world.f90 <==
subroutine my_fortran_sub_1 (A) bind(C)
  real :: A(:, :, :)
  print *, 'Lower bounds: ', lbound(A) ! Lower bounds:    1    1    1
  print *, 'Upper bounds: ', ubound(A) ! Upper bounds:   21    6    8
end
subroutine my_fortran_sub_2 (A) bind(C)
  real, ALLOCATABLE :: A(:, :, :)
  print *, 'Lower bounds: ', lbound(A)
  print *, 'Upper bounds: ', ubound(A)
end subroutine my_fortran_sub_2

Reply via email to