/* 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);

/* NOTE: Since GCC 12, the FE generates code to do the conversion
   directly without calling this function.  */
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);

/* NOTE: Since GCC 12, the FE generates code to do the conversion
   directly without calling this function.  */
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;
}
