blob: ed2d84f91a4261d6f5f49d626cd603d08c246c2a [file] [log] [blame]
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ISO_Fortran_binding.h>
#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 ();
}