#include #include #include #include #include #include "dump-descriptors.h" struct s { int i; double d; }; /* External entry point. */ extern void ctest (void); void ctest (void) { CFI_CDESC_T(3) desc; CFI_cdesc_t *dv = (CFI_cdesc_t *) &desc; CFI_index_t ex[3], lb[3], ub[3]; CFI_index_t sm; int i; /* Allocate and deallocate a scalar. */ sm = sizeof (struct s); check_CFI_status ("CFI_establish", CFI_establish (dv, NULL, CFI_attribute_allocatable, CFI_type_struct, sm, 0, NULL)); check_CFI_status ("CFI_allocate", CFI_allocate (dv, NULL, NULL, 69)); dump_CFI_cdesc_t (dv); if (dv->base_addr == NULL) abort (); /* The elem_len argument only overrides the initial value in the descriptor for character types. */ if (dv->elem_len != sm) abort (); check_CFI_status ("CFI_deallocate", CFI_deallocate (dv)); /* The base_addr member of the C descriptor becomes a null pointer. */ if (dv->base_addr != NULL) abort (); /* Try an array. We are going to test the requirement that: The supplied lower and upper bounds override any current dimension information in the C descriptor. so we'll stuff different values in the descriptor to start with. */ ex[0] = 3; ex[1] = 4; ex[2] = 5; check_CFI_status ("CFI_establish", CFI_establish (dv, NULL, CFI_attribute_pointer, CFI_type_double, 0, 3, ex)); lb[0] = 1; lb[1] = 2; lb[2] = 3; ub[0] = 10; ub[1] = 5; ub[2] = 10; sm = sizeof (double); check_CFI_status ("CFI_allocate", CFI_allocate (dv, lb, ub, 20)); dump_CFI_cdesc_t (dv); if (dv->base_addr == NULL) abort (); /* The element sizes passed to both CFI_establish and CFI_allocate should have been ignored in favor of using the constant size of the type. */ if (dv->elem_len != sm) abort (); /* Check extents and strides; we expect the allocated array to be contiguous so the stride computation should be straightforward no matter what the lower bound is. */ for (i = 0; i < 3; i++) { CFI_index_t extent = ub[i] - lb[i] + 1; if (dv->dim[i].lower_bound != lb[i]) abort (); if (dv->dim[i].extent != extent) abort (); /* pr93524 */ if (dv->dim[i].sm != sm) abort (); sm *= extent; } check_CFI_status ("CFI_deallocate", CFI_deallocate (dv)); if (dv->base_addr != NULL) abort (); /* Similarly for a character array, except that we expect the elem_len provided to CFI_allocate to prevail. We set the elem_len to the same size as the array element in the previous example, so the bounds and strides should all be the same. */ ex[0] = 3; ex[1] = 4; ex[2] = 5; check_CFI_status ("CFI_establish", CFI_establish (dv, NULL, CFI_attribute_allocatable, CFI_type_char, 4, 3, ex)); lb[0] = 1; lb[1] = 2; lb[2] = 3; ub[0] = 10; ub[1] = 5; ub[2] = 10; sm = sizeof (double); check_CFI_status ("CFI_allocate", CFI_allocate (dv, lb, ub, sm)); dump_CFI_cdesc_t (dv); if (dv->base_addr == NULL) abort (); if (dv->elem_len != sm) abort (); /* Check extents and strides; we expect the allocated array to be contiguous so the stride computation should be straightforward no matter what the lower bound is. */ for (i = 0; i < 3; i++) { CFI_index_t extent = ub[i] - lb[i] + 1; if (dv->dim[i].lower_bound != lb[i]) abort (); if (dv->dim[i].extent != extent) abort (); /* pr93524 */ if (dv->dim[i].sm != sm) abort (); sm *= extent; } check_CFI_status ("CFI_deallocate", CFI_deallocate (dv)); if (dv->base_addr != NULL) abort (); /* Signed char is not a Fortran character type. Here we expect it to ignore the elem_len argument and use the size of the type. */ ex[0] = 3; ex[1] = 4; ex[2] = 5; check_CFI_status ("CFI_establish", CFI_establish (dv, NULL, CFI_attribute_allocatable, CFI_type_signed_char, 4, 3, ex)); lb[0] = 1; lb[1] = 2; lb[2] = 3; ub[0] = 10; ub[1] = 5; ub[2] = 10; sm = sizeof (double); check_CFI_status ("CFI_allocate", CFI_allocate (dv, lb, ub, sm)); dump_CFI_cdesc_t (dv); if (dv->base_addr == NULL) abort (); if (dv->elem_len != sizeof (signed char)) abort (); check_CFI_status ("CFI_deallocate", CFI_deallocate (dv)); if (dv->base_addr != NULL) abort (); }