/* Functions to convert descriptors between CFI and gfortran
   and the CFI function declarations whose prototypes appear
   in ISO_Fortran_binding.h.
   Copyright (C) 2018-2021 Free Software Foundation, Inc.
   Contributed by Daniel Celis Garza  <celisdanieljr@gmail.com>
	       and Paul Thomas  <pault@gcc.gnu.org>

This file is part of the GNU Fortran runtime library (libgfortran).

Libgfortran is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.

Libgfortran is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "libgfortran.h"
#include "ISO_Fortran_binding.h"
#include <string.h>
#include <inttypes.h>   /* for PRIiPTR */

extern void cfi_desc_to_gfc_desc (gfc_array_void *, CFI_cdesc_t **);
export_proto(cfi_desc_to_gfc_desc);

void
cfi_desc_to_gfc_desc (gfc_array_void *d, CFI_cdesc_t **s_ptr)
{
  signed char type;
  size_t size;
  int n;
  CFI_cdesc_t *s = *s_ptr;

  if (!s)
    return;

  /* Verify descriptor.  */
  switch (s->attribute)
    {
    case CFI_attribute_pointer:
    case CFI_attribute_allocatable:
      break;
    case CFI_attribute_other:
      if (s->base_addr)
	break;
      runtime_error ("Nonallocatable, nonpointer actual argument to BIND(C) "
		     "dummy argument where the effective argument is either "
		     "not allocated or not associated");
      break;
    default:
      runtime_error ("Invalid attribute type %d in CFI_cdesc_t descriptor",
		     (int) s->attribute);
      break;
    }
  GFC_DESCRIPTOR_DATA (d) = s->base_addr;

  /* Correct the unfortunate difference in order with types.  */
  type = (signed char)(s->type & CFI_type_mask);
  switch (type)
    {
    case CFI_type_Character:
      type = BT_CHARACTER;
      break;
    case CFI_type_struct:
      type = BT_DERIVED;
      break;
    case CFI_type_cptr:
      /* FIXME: PR 100915.  GFC descriptors do not distinguish between
	 CFI_type_cptr and CFI_type_cfunptr.  */
      type = BT_VOID;
      break;
    default:
      break;
    }

  GFC_DESCRIPTOR_TYPE (d) = type;
  GFC_DESCRIPTOR_SIZE (d) = s->elem_len;

  d->dtype.version = 0;

  if (s->rank < 0 || s->rank > CFI_MAX_RANK)
    internal_error (NULL, "Invalid rank in descriptor");
  GFC_DESCRIPTOR_RANK (d) = (signed char)s->rank;

  d->dtype.attribute = (signed short)s->attribute;

  if (s->rank)
    {
      if ((size_t)s->dim[0].sm % s->elem_len)
	d->span = (index_type)s->dim[0].sm;
      else
	d->span = (index_type)s->elem_len;
    }

  d->offset = 0;
  if (GFC_DESCRIPTOR_DATA (d))
    for (n = 0; n < GFC_DESCRIPTOR_RANK (d); n++)
      {
	CFI_index_t lb = 1;

	if (s->attribute != CFI_attribute_other)
	  lb = s->dim[n].lower_bound;

	GFC_DESCRIPTOR_LBOUND(d, n) = (index_type)lb;
	GFC_DESCRIPTOR_UBOUND(d, n) = (index_type)(s->dim[n].extent + lb - 1);
	GFC_DESCRIPTOR_STRIDE(d, n) = (index_type)(s->dim[n].sm / s->elem_len);
	d->offset -= GFC_DESCRIPTOR_STRIDE(d, n) * GFC_DESCRIPTOR_LBOUND(d, n);
      }
}

extern void gfc_desc_to_cfi_desc (CFI_cdesc_t **, const gfc_array_void *);
export_proto(gfc_desc_to_cfi_desc);

void
gfc_desc_to_cfi_desc (CFI_cdesc_t **d_ptr, const gfc_array_void *s)
{
  int n;
  CFI_cdesc_t *d;
  signed char type, kind;

  /* Play it safe with allocation of the flexible array member 'dim'
     by setting the length to CFI_MAX_RANK. This should not be necessary
     but valgrind complains accesses after the allocated block.  */
  if (*d_ptr == NULL)
    d = calloc (1, (sizeof (CFI_cdesc_t)
		    + (CFI_type_t)(CFI_MAX_RANK * sizeof (CFI_dim_t))));
  else
    d = *d_ptr;

  /* Verify descriptor.  */
  switch (s->dtype.attribute)
    {
    case CFI_attribute_pointer:
    case CFI_attribute_allocatable:
      break;
    case CFI_attribute_other:
      if (s->base_addr)
	break;
      runtime_error ("Nonallocatable, nonpointer actual argument to BIND(C) "
		     "dummy argument where the effective argument is either "
		     "not allocated or not associated");
      break;
    default:
      internal_error (NULL, "Invalid attribute in gfc_array descriptor");
      break;
    }
  d->base_addr = GFC_DESCRIPTOR_DATA (s);
  d->elem_len = GFC_DESCRIPTOR_SIZE (s);
  if (d->elem_len <= 0)
    internal_error (NULL, "Invalid size in descriptor");

  d->version = CFI_VERSION;

  d->rank = (CFI_rank_t)GFC_DESCRIPTOR_RANK (s);
  if (d->rank < 0 || d->rank > CFI_MAX_RANK)
    internal_error (NULL, "Invalid rank in descriptor");

  d->attribute = (CFI_attribute_t)s->dtype.attribute;

  type = GFC_DESCRIPTOR_TYPE (s);
  switch (type)
    {
    case BT_CHARACTER:
      d->type = CFI_type_Character;
      break;
    case BT_DERIVED:
      d->type = CFI_type_struct;
      break;
    case BT_VOID:
      /* FIXME: PR 100915.  GFC descriptors do not distinguish between
	 CFI_type_cptr and CFI_type_cfunptr.  */
      d->type = CFI_type_cptr;
      break;
    default:
      d->type = (CFI_type_t)type;
      break;
    }

  switch (d->type)
    {
    case CFI_type_Integer:
    case CFI_type_Logical:
    case CFI_type_Real:
      kind = (signed char)d->elem_len;
      break;
    case CFI_type_Complex:
      kind = (signed char)(d->elem_len >> 1);
      break;
    case CFI_type_Character:
      /* FIXME: we can't distinguish between kind/len because
	 the GFC descriptor only encodes the elem_len..
	 Until PR92482 is fixed, assume elem_len refers to the
	 character size and not the string length.  */
      kind = (signed char)d->elem_len;
      break;
    case CFI_type_struct:
    case CFI_type_cptr:
    case CFI_type_other:
      /* FIXME: PR 100915.  GFC descriptors do not distinguish between
	 CFI_type_cptr and CFI_type_cfunptr.  */
      kind = 0;
      break;
    default:
      internal_error (NULL, "Invalid type in descriptor");
    }

  if (kind < 0)
    internal_error (NULL, "Invalid kind in descriptor");

  /* FIXME: This is PR100917.  Because the GFC descriptor encodes only the
     elem_len and not the kind, we get into trouble with long double kinds
     that do not correspond directly to the elem_len, specifically the
     kind 10 80-bit long double on x86 targets.  On x86_64, this has size
     16 and cannot be differentiated from true _Float128.  Prefer the
     standard long double type over the GNU extension in that case.  */
  if (d->type == CFI_type_Real && kind == sizeof (long double))
    d->type = CFI_type_long_double;
  else if (d->type == CFI_type_Complex && kind == sizeof (long double))
    d->type = CFI_type_long_double_Complex;
  else
    d->type = (CFI_type_t)(d->type
			   + ((CFI_type_t)kind << CFI_type_kind_shift));

  if (d->base_addr)
    /* Full pointer or allocatable arrays retain their lower_bounds.  */
    for (n = 0; n < GFC_DESCRIPTOR_RANK (s); n++)
      {
	if (d->attribute != CFI_attribute_other)
	  d->dim[n].lower_bound = (CFI_index_t)GFC_DESCRIPTOR_LBOUND(s, n);
	else
	  d->dim[n].lower_bound = 0;

	/* Assumed size arrays have gfc ubound == 0 and CFI extent = -1.  */
	if (n == GFC_DESCRIPTOR_RANK (s) - 1
	    && GFC_DESCRIPTOR_LBOUND(s, n) == 1
	    && GFC_DESCRIPTOR_UBOUND(s, n) == 0)
	  d->dim[n].extent = -1;
	else
	  d->dim[n].extent = (CFI_index_t)GFC_DESCRIPTOR_UBOUND(s, n)
			     - (CFI_index_t)GFC_DESCRIPTOR_LBOUND(s, n) + 1;
	d->dim[n].sm = (CFI_index_t)(GFC_DESCRIPTOR_STRIDE(s, n) * s->span);
      }

  if (*d_ptr == NULL)
    *d_ptr = d;
}

void *CFI_address (const CFI_cdesc_t *dv, const CFI_index_t subscripts[])
{
  int i;
  char *base_addr = (char *)dv->base_addr;

  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptor must not be NULL. */
      if (dv == NULL)
	{
	  fprintf (stderr, "CFI_address: C descriptor is NULL.\n");
	  return NULL;
	}

      /* Base address of C descriptor must not be NULL. */
      if (dv->base_addr == NULL)
	{
	  fprintf (stderr, "CFI_address: base address of C descriptor "
		   "must not be NULL.\n");
	  return NULL;
	}
    }

  /* Return base address if C descriptor is a scalar. */
  if (dv->rank == 0)
    return dv->base_addr;

  /* Calculate the appropriate base address if dv is not a scalar. */
  else
    {
      /* Base address is the C address of the element of the object
	 specified by subscripts. */
      for (i = 0; i < dv->rank; i++)
	{
	  CFI_index_t idx = subscripts[i] - dv->dim[i].lower_bound;
	  if (unlikely (compile_options.bounds_check)
	      && ((dv->dim[i].extent != -1 && idx >= dv->dim[i].extent)
		  || idx < 0))
	    {
	      fprintf (stderr, "CFI_address: subscripts[%d] is out of "
		       "bounds. For dimension = %d, subscripts = %d, "
		       "lower_bound = %" PRIiPTR ", upper bound = %" PRIiPTR
		       ", extent = %" PRIiPTR "\n",
		       i, i, (int)subscripts[i],
		       (ptrdiff_t)dv->dim[i].lower_bound,
		       (ptrdiff_t)(dv->dim[i].extent - dv->dim[i].lower_bound),
		       (ptrdiff_t)dv->dim[i].extent);
              return NULL;
            }

	  base_addr = base_addr + (CFI_index_t)(idx * dv->dim[i].sm);
	}
    }

  return (void *)base_addr;
}


int
CFI_allocate (CFI_cdesc_t *dv, const CFI_index_t lower_bounds[],
	      const CFI_index_t upper_bounds[], size_t elem_len)
{
  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptor must not be NULL. */
      if (dv == NULL)
	{
	  fprintf (stderr, "CFI_allocate: C descriptor is NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      /* The C descriptor must be for an allocatable or pointer object. */
      if (dv->attribute == CFI_attribute_other)
	{
	  fprintf (stderr, "CFI_allocate: The object of the C descriptor "
		   "must be a pointer or allocatable variable.\n");
	  return CFI_INVALID_ATTRIBUTE;
	}

      /* Base address of C descriptor must be NULL. */
      if (dv->base_addr != NULL)
	{
	  fprintf (stderr, "CFI_allocate: Base address of C descriptor "
		   "must be NULL.\n");
	  return CFI_ERROR_BASE_ADDR_NOT_NULL;
	}
    }

  /* If the type is a Fortran character type, the descriptor's element
     length is replaced by the elem_len argument. */
  if (dv->type == CFI_type_char || dv->type == CFI_type_ucs4_char)
    dv->elem_len = elem_len;

  /* Dimension information and calculating the array length. */
  size_t arr_len = 1;

  /* If rank is greater than 0, lower_bounds and upper_bounds are used. They're
     ignored otherwise. */
  if (dv->rank > 0)
    {
      if (unlikely (compile_options.bounds_check)
	  && (lower_bounds == NULL || upper_bounds == NULL))
	{
	  fprintf (stderr, "CFI_allocate: The lower_bounds and "
		   "upper_bounds arguments must be non-NULL when "
		   "rank is greater than zero.\n");
	  return CFI_INVALID_EXTENT;
	}

      for (int i = 0; i < dv->rank; i++)
	{
	  dv->dim[i].lower_bound = lower_bounds[i];
	  dv->dim[i].extent = upper_bounds[i] - dv->dim[i].lower_bound + 1;
	  dv->dim[i].sm = dv->elem_len * arr_len;
	  arr_len *= dv->dim[i].extent;
        }
    }

  dv->base_addr = calloc (arr_len, dv->elem_len);
  if (dv->base_addr == NULL)
    {
      fprintf (stderr, "CFI_allocate: Failure in memory allocation.\n");
      return CFI_ERROR_MEM_ALLOCATION;
    }

  return CFI_SUCCESS;
}


int
CFI_deallocate (CFI_cdesc_t *dv)
{
  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptor must not be NULL */
      if (dv == NULL)
	{
	  fprintf (stderr, "CFI_deallocate: C descriptor is NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      /* Base address must not be NULL. */
      if (dv->base_addr == NULL)
	{
	  fprintf (stderr, "CFI_deallocate: Base address is already NULL.\n");
	  return CFI_ERROR_BASE_ADDR_NULL;
	}

      /* C descriptor must be for an allocatable or pointer variable. */
      if (dv->attribute == CFI_attribute_other)
	{
	  fprintf (stderr, "CFI_deallocate: C descriptor must describe a "
		  "pointer or allocatable object.\n");
	  return CFI_INVALID_ATTRIBUTE;
	}
    }

  /* Free and nullify memory. */
  free (dv->base_addr);
  dv->base_addr = NULL;

  return CFI_SUCCESS;
}


int CFI_establish (CFI_cdesc_t *dv, void *base_addr, CFI_attribute_t attribute,
		   CFI_type_t type, size_t elem_len, CFI_rank_t rank,
		   const CFI_index_t extents[])
{
  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptor must not be NULL. */
      if (dv == NULL)
	{
	  fprintf (stderr, "CFI_establish: C descriptor is NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      /* Rank must be between 0 and CFI_MAX_RANK. */
      if (rank < 0 || rank > CFI_MAX_RANK)
	{
	  fprintf (stderr, "CFI_establish: Rank must be between 0 and %d, "
		   "0 < rank (0 !< %d).\n", CFI_MAX_RANK, (int)rank);
	  return CFI_INVALID_RANK;
	}

      /* If base address is not NULL, the established C descriptor is for a
	  nonallocatable entity. */
      if (attribute == CFI_attribute_allocatable && base_addr != NULL)
	{
	  fprintf (stderr, "CFI_establish: If base address is not NULL, "
		   "the established C descriptor must be "
		   "for a nonallocatable entity.\n");
	  return CFI_INVALID_ATTRIBUTE;
	}
    }

  dv->base_addr = base_addr;

  if (type == CFI_type_char || type == CFI_type_ucs4_char
      || type == CFI_type_struct || type == CFI_type_other)
    {
      /* Note that elem_len has type size_t, which is unsigned.  */
      if (unlikely (compile_options.bounds_check) && elem_len == 0)
	{
	  fprintf (stderr, "CFI_establish: The supplied elem_len must "
		   "be greater than zero.\n");
	  return CFI_INVALID_ELEM_LEN;
	}
      dv->elem_len = elem_len;
    }
  else if (type == CFI_type_cptr)
    dv->elem_len = sizeof (void *);
  else if (type == CFI_type_cfunptr)
    dv->elem_len = sizeof (void (*)(void));
  else if (unlikely (compile_options.bounds_check) && type < 0)
    {
      fprintf (stderr, "CFI_establish: Invalid type (type = %d).\n",
	       (int)type);
      return CFI_INVALID_TYPE;
    }
  else
    {
      /* base_type describes the intrinsic type with kind parameter. */
      size_t base_type = type & CFI_type_mask;
      /* base_type_size is the size in bytes of the variable as given by its
       * kind parameter. */
      size_t base_type_size = (type - base_type) >> CFI_type_kind_shift;
      /* Kind type 10 maps onto the 80-bit long double encoding on x86.
	 Note that this has different storage size for -m32 than -m64.  */
      if (base_type_size == 10)
	base_type_size = sizeof (long double);
      /* Complex numbers are twice the size of their real counterparts. */
      if (base_type == CFI_type_Complex)
	base_type_size *= 2;
      dv->elem_len = base_type_size;
    }

  dv->version = CFI_VERSION;
  dv->rank = rank;
  dv->attribute = attribute;
  dv->type = type;

  /* Extents must not be NULL if rank is greater than zero and base_addr is not
     NULL */
  if (rank > 0 && base_addr != NULL)
    {
      if (unlikely (compile_options.bounds_check) && extents == NULL)
        {
	  fprintf (stderr, "CFI_establish: Extents must not be NULL "
		   "if rank is greater than zero and base address is "
		   "not NULL.\n");
	  return CFI_INVALID_EXTENT;
	}

      for (int i = 0; i < rank; i++)
	{
	  /* The standard requires all dimensions to be nonnegative.
	     Apparently you can have an extent-zero dimension but can't
	     construct an assumed-size array with -1 as the extent
	     of the last dimension.  */
	  if (unlikely (compile_options.bounds_check) && extents[i] < 0)
	    {
	      fprintf (stderr, "CFI_establish: Extents must be nonnegative "
		       "(extents[%d] = %" PRIiPTR ").\n",
		       i, (ptrdiff_t)extents[i]);
	      return CFI_INVALID_EXTENT;
	    }
	  dv->dim[i].lower_bound = 0;
	  dv->dim[i].extent = extents[i];
	  if (i == 0)
	    dv->dim[i].sm = dv->elem_len;
	  else
	    {
	      CFI_index_t extents_product = 1;
	      for (int j = 0; j < i; j++)
		extents_product *= extents[j];
	      dv->dim[i].sm = (CFI_index_t)(dv->elem_len * extents_product);
	    }
	}
    }

  return CFI_SUCCESS;
}


int CFI_is_contiguous (const CFI_cdesc_t *dv)
{
  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptor must not be NULL. */
      if (dv == NULL)
	{
	  fprintf (stderr, "CFI_is_contiguous: C descriptor is NULL.\n");
	  return 0;
	}

      /* Base address must not be NULL. */
      if (dv->base_addr == NULL)
	{
	  fprintf (stderr, "CFI_is_contiguous: Base address of C descriptor "
		   "is already NULL.\n");
	  return 0;
	}

      /* Must be an array. */
      if (dv->rank <= 0)
	{
	  fprintf (stderr, "CFI_is_contiguous: C descriptor must describe "
		   "an array.\n");
	  return 0;
	}
    }

  /* Assumed size arrays are always contiguous.  */
  if (dv->rank > 0 && dv->dim[dv->rank - 1].extent == -1)
    return 1;

  /* If an array is not contiguous the memory stride is different to
     the element length. */
  for (int i = 0; i < dv->rank; i++)
    {
      if (i == 0 && dv->dim[i].sm == (CFI_index_t)dv->elem_len)
	continue;
      else if (i > 0
	       && dv->dim[i].sm == (CFI_index_t)(dv->dim[i - 1].sm
				   * dv->dim[i - 1].extent))
	continue;

      return 0;
    }

  /* Array sections are guaranteed to be contiguous by the previous test.  */
  return 1;
}


int CFI_section (CFI_cdesc_t *result, const CFI_cdesc_t *source,
		 const CFI_index_t lower_bounds[],
		 const CFI_index_t upper_bounds[], const CFI_index_t strides[])
{
  /* Dimension information. */
  CFI_index_t lower[CFI_MAX_RANK];
  CFI_index_t upper[CFI_MAX_RANK];
  CFI_index_t stride[CFI_MAX_RANK];
  int zero_count = 0;

  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptors must not be NULL. */
      if (source == NULL)
	{
	  fprintf (stderr, "CFI_section: Source must not be NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      if (result == NULL)
	{
	  fprintf (stderr, "CFI_section: Result must not be NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      /* Base address of source must not be NULL. */
      if (source->base_addr == NULL)
	{
	  fprintf (stderr, "CFI_section: Base address of source must "
		   "not be NULL.\n");
	  return CFI_ERROR_BASE_ADDR_NULL;
	}

      /* Result must not be an allocatable array. */
      if (result->attribute == CFI_attribute_allocatable)
	{
	  fprintf (stderr, "CFI_section: Result must not describe an "
		   "allocatable array.\n");
	  return CFI_INVALID_ATTRIBUTE;
	}

      /* Source must be some form of array (nonallocatable nonpointer array,
	 allocated allocatable array or an associated pointer array). */
      if (source->rank <= 0)
	{
	  fprintf (stderr, "CFI_section: Source must describe an array.\n");
	  return CFI_INVALID_RANK;
	}

      /* Element lengths of source and result must be equal. */
      if (result->elem_len != source->elem_len)
	{
	  fprintf (stderr, "CFI_section: The element lengths of "
		   "source (source->elem_len = %" PRIiPTR ") and result "
		   "(result->elem_len = %" PRIiPTR ") must be equal.\n",
		   (ptrdiff_t)source->elem_len, (ptrdiff_t)result->elem_len);
	  return CFI_INVALID_ELEM_LEN;
	}

      /* Types must be equal. */
      if (result->type != source->type)
	{
	  fprintf (stderr, "CFI_section: Types of source "
		   "(source->type = %d) and result (result->type = %d) "
		   "must be equal.\n", source->type, result->type);
	  return CFI_INVALID_TYPE;
	}
    }

  /* Stride of zero in the i'th dimension means rank reduction in that
     dimension. */
  for (int i = 0; i < source->rank; i++)
    {
      if (strides[i] == 0)
	zero_count++;
    }

  /* Rank of result must be equal the the rank of source minus the number of
   * zeros in strides. */
  if (unlikely (compile_options.bounds_check)
      && result->rank != source->rank - zero_count)
    {
      fprintf (stderr, "CFI_section: Rank of result must be equal to the "
		       "rank of source minus the number of zeros in strides "
		       "(result->rank = source->rank - zero_count, %d != %d "
		       "- %d).\n", result->rank, source->rank, zero_count);
      return CFI_INVALID_RANK;
    }

  /* Lower bounds. */
  if (lower_bounds == NULL)
    {
      for (int i = 0; i < source->rank; i++)
	lower[i] = source->dim[i].lower_bound;
    }
  else
    {
      for (int i = 0; i < source->rank; i++)
	lower[i] = lower_bounds[i];
    }

  /* Upper bounds. */
  if (upper_bounds == NULL)
    {
      if (unlikely (compile_options.bounds_check)
	  && source->dim[source->rank - 1].extent == -1)
        {
	  fprintf (stderr, "CFI_section: Source must not be an assumed-size "
		   "array if upper_bounds is NULL.\n");
	  return CFI_INVALID_EXTENT;
	}

      for (int i = 0; i < source->rank; i++)
	upper[i] = source->dim[i].lower_bound + source->dim[i].extent - 1;
    }
  else
    {
      for (int i = 0; i < source->rank; i++)
	upper[i] = upper_bounds[i];
    }

  /* Stride */
  if (strides == NULL)
    {
      for (int i = 0; i < source->rank; i++)
	stride[i] = 1;
    }
  else
    {
      for (int i = 0; i < source->rank; i++)
	{
	  stride[i] = strides[i];
	  /* If stride[i] == 0 then lower[i] and upper[i] must be equal. */
	  if (unlikely (compile_options.bounds_check)
	      && stride[i] == 0 && lower[i] != upper[i])
	    {
	      fprintf (stderr, "CFI_section: If strides[%d] = 0, then "
		       "lower_bounds[%d] = %" PRIiPTR " and "
		       "upper_bounds[%d] = %" PRIiPTR " must be equal.\n",
		       i, i, (ptrdiff_t)lower_bounds[i], i,
		       (ptrdiff_t)upper_bounds[i]);
	      return CFI_ERROR_OUT_OF_BOUNDS;
	    }
	}
    }

  /* Check that section upper and lower bounds are within the array bounds. */
  if (unlikely (compile_options.bounds_check))
    for (int i = 0; i < source->rank; i++)
      {
	bool assumed_size
	  = (i == source->rank - 1 && source->dim[i].extent == -1);
	CFI_index_t ub
	  = source->dim[i].lower_bound + source->dim[i].extent - 1;
	if (lower_bounds != NULL
	    && (lower[i] < source->dim[i].lower_bound
		|| (!assumed_size && lower[i] > ub)))
	  {
	    fprintf (stderr, "CFI_section: Lower bounds must be within "
		     "the bounds of the Fortran array "
		     "(source->dim[%d].lower_bound "
		     "<= lower_bounds[%d] <= source->dim[%d].lower_bound "
		     "+ source->dim[%d].extent - 1, "
		     "%" PRIiPTR " <= %" PRIiPTR " <= %" PRIiPTR ").\n",
		     i, i, i, i,
		     (ptrdiff_t)source->dim[i].lower_bound,
		     (ptrdiff_t)lower[i],
		     (ptrdiff_t)ub);
	    return CFI_ERROR_OUT_OF_BOUNDS;
	  }

	if (upper_bounds != NULL
	    && (upper[i] < source->dim[i].lower_bound
		|| (!assumed_size && upper[i] > ub)))
	  {
	    fprintf (stderr, "CFI_section: Upper bounds must be within "
		     "the bounds of the Fortran array "
		     "(source->dim[%d].lower_bound "
		     "<= upper_bounds[%d] <= source->dim[%d].lower_bound "
		     "+ source->dim[%d].extent - 1, "
		     "%" PRIiPTR " !<= %" PRIiPTR " !<= %" PRIiPTR ").\n",
		     i, i, i, i,
		     (ptrdiff_t)source->dim[i].lower_bound,
		     (ptrdiff_t)upper[i],
		     (ptrdiff_t)ub);
	    return CFI_ERROR_OUT_OF_BOUNDS;
	  }

	if (upper[i] < lower[i] && stride[i] >= 0)
	  {
	    fprintf (stderr, "CFI_section: If the upper bound is smaller than "
		     "the lower bound for a given dimension (upper[%d] < "
		     "lower[%d], %" PRIiPTR " < %" PRIiPTR "), then the "
		     "stride for said dimension must be negative "
		     "(stride[%d] < 0, %" PRIiPTR " < 0).\n",
		     i, i, (ptrdiff_t)upper[i], (ptrdiff_t)lower[i],
		     i, (ptrdiff_t)stride[i]);
	    return CFI_INVALID_STRIDE;
	  }
      }

  /* Set the base address.  We have to compute this first in the case
     where source == result, before we overwrite the dimension data.  */
  result->base_addr = CFI_address (source, lower);

  /* Set the appropriate dimension information that gives us access to the
   * data. */
  for (int i = 0, o = 0; i < source->rank; i++)
    {
      if (stride[i] == 0)
	continue;
      result->dim[o].lower_bound = 0;
      result->dim[o].extent = 1 + (upper[i] - lower[i])/stride[i];
      result->dim[o].sm = stride[i] * source->dim[i].sm;
      o++;
    }

  return CFI_SUCCESS;
}


int CFI_select_part (CFI_cdesc_t *result, const CFI_cdesc_t *source,
		     size_t displacement, size_t elem_len)
{
  if (unlikely (compile_options.bounds_check))
    {
      /* C descriptors must not be NULL. */
      if (source == NULL)
	{
	  fprintf (stderr, "CFI_select_part: Source must not be NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      if (result == NULL)
	{
	  fprintf (stderr, "CFI_select_part: Result must not be NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}

      /* Attribute of result will be CFI_attribute_other or
	 CFI_attribute_pointer. */
      if (result->attribute == CFI_attribute_allocatable)
	{
	  fprintf (stderr, "CFI_select_part: Result must not describe an "
		   "allocatable object (result->attribute != %d).\n",
		   CFI_attribute_allocatable);
	  return CFI_INVALID_ATTRIBUTE;
	}

      /* Base address of source must not be NULL. */
      if (source->base_addr == NULL)
	{
	  fprintf (stderr, "CFI_select_part: Base address of source must "
		   "not be NULL.\n");
	  return CFI_ERROR_BASE_ADDR_NULL;
	}

      /* Source and result must have the same rank. */
      if (source->rank != result->rank)
	{
	  fprintf (stderr, "CFI_select_part: Source and result must have "
		   "the same rank (source->rank = %d, result->rank = %d).\n",
		   (int)source->rank, (int)result->rank);
	  return CFI_INVALID_RANK;
	}

      /* Nonallocatable nonpointer must not be an assumed size array. */
      if (source->rank > 0 && source->dim[source->rank - 1].extent == -1)
	{
	  fprintf (stderr, "CFI_select_part: Source must not describe an "
		   "assumed size array  (source->dim[%d].extent != -1).\n",
		   source->rank - 1);
	  return CFI_INVALID_DESCRIPTOR;
	}
    }

  /* Element length is ignored unless result->type specifies a Fortran
     character type.  */
  if (result->type == CFI_type_char || result->type == CFI_type_ucs4_char)
    result->elem_len = elem_len;

  if (unlikely (compile_options.bounds_check))
    {
      /* Ensure displacement is within the bounds of the element length
	 of source.*/
      if (displacement > source->elem_len - 1)
	{
	  fprintf (stderr, "CFI_select_part: Displacement must be within the "
		   "bounds of source (0 <= displacement <= source->elem_len "
		   "- 1, 0 <= %" PRIiPTR " <= %" PRIiPTR ").\n",
		   (ptrdiff_t)displacement,
		   (ptrdiff_t)(source->elem_len - 1));
	  return CFI_ERROR_OUT_OF_BOUNDS;
	}

      /* Ensure displacement and element length of result are less than or
	 equal to the element length of source. */
      if (displacement + result->elem_len > source->elem_len)
	{
	  fprintf (stderr, "CFI_select_part: Displacement plus the element "
		   "length of result must be less than or equal to the "
		   "element length of source (displacement + result->elem_len "
		   "<= source->elem_len, "
		   "%" PRIiPTR " + %" PRIiPTR " = %" PRIiPTR " <= %" PRIiPTR
		   ").\n",
		   (ptrdiff_t)displacement, (ptrdiff_t)result->elem_len,
		   (ptrdiff_t)(displacement + result->elem_len),
		   (ptrdiff_t)source->elem_len);
	  return CFI_ERROR_OUT_OF_BOUNDS;
	}
    }

  if (result->rank > 0)
    {
      for (int i = 0; i < result->rank; i++)
	{
	  result->dim[i].lower_bound = source->dim[i].lower_bound;
	  result->dim[i].extent = source->dim[i].extent;
	  result->dim[i].sm = source->dim[i].sm;
        }
    }

  result->base_addr = (char *) source->base_addr + displacement;
  return CFI_SUCCESS;
}


int CFI_setpointer (CFI_cdesc_t *result, CFI_cdesc_t *source,
		    const CFI_index_t lower_bounds[])
{
  /* Result must not be NULL and must be a Fortran pointer. */
  if (unlikely (compile_options.bounds_check))
    {
      if (result == NULL)
	{
	  fprintf (stderr, "CFI_setpointer: Result is NULL.\n");
	  return CFI_INVALID_DESCRIPTOR;
	}
      
      if (result->attribute != CFI_attribute_pointer)
	{
 	  fprintf (stderr, "CFI_setpointer: Result shall be the address of a "
		   "C descriptor for a Fortran pointer.\n");
 	  return CFI_INVALID_ATTRIBUTE;
 	}
    }
      
  /* If source is NULL, the result is a C descriptor that describes a
   * disassociated pointer. */
  if (source == NULL)
    {
      result->base_addr = NULL;
      result->version  = CFI_VERSION;
    }
  else
    {
      /* Check that the source is valid and that element lengths, ranks
	 and types of source and result are the same. */
      if (unlikely (compile_options.bounds_check))
	{
	  if (source->base_addr == NULL
	      && source->attribute == CFI_attribute_allocatable)
	    {
	      fprintf (stderr, "CFI_setpointer: The source is an "
		       "allocatable object but is not allocated.\n");
	      return CFI_ERROR_BASE_ADDR_NULL;
	    }
	  if (source->rank > 0
	      && source->dim[source->rank - 1].extent == -1)
	    {
	      fprintf (stderr, "CFI_setpointer: The source is an "
		       "assumed-size array.\n");
	      return CFI_INVALID_EXTENT;
	    }
	  if (result->elem_len != source->elem_len)
	    {
	      fprintf (stderr, "CFI_setpointer: Element lengths of result "
		       "(result->elem_len = %" PRIiPTR ") and source "
		       "(source->elem_len = %" PRIiPTR ") "
		       " must be the same.\n",
		       (ptrdiff_t)result->elem_len,
		       (ptrdiff_t)source->elem_len);
	      return CFI_INVALID_ELEM_LEN;
	    }

	  if (result->rank != source->rank)
	    {
	      fprintf (stderr, "CFI_setpointer: Ranks of result "
		       "(result->rank = %d) and source (source->rank = %d) "
		       "must be the same.\n", result->rank, source->rank);
	      return CFI_INVALID_RANK;
	    }

	  if (result->type != source->type)
	    {
	      fprintf (stderr, "CFI_setpointer: Types of result "
		       "(result->type = %d) and source (source->type = %d) "
		       "must be the same.\n", result->type, source->type);
	      return CFI_INVALID_TYPE;
	    }
	}

      /* If the source is a disassociated pointer, the result must also
	 describe a disassociated pointer. */
      if (source->base_addr == NULL
	  && source->attribute == CFI_attribute_pointer)
	result->base_addr = NULL;
      else
	result->base_addr = source->base_addr;

      /* Assign components to result. */
      result->version = source->version;

      /* Dimension information. */
      for (int i = 0; i < source->rank; i++)
	{
	  if (lower_bounds != NULL)
	    result->dim[i].lower_bound = lower_bounds[i];
	  else
	    result->dim[i].lower_bound = source->dim[i].lower_bound;

	  result->dim[i].extent = source->dim[i].extent;
	  result->dim[i].sm = source->dim[i].sm;
	}
    }

  return CFI_SUCCESS;
}
