(root)/
gcc-13.2.0/
gcc/
testsuite/
gfortran.dg/
c-interop/
allocate-errors-c.c
       1  #include <stdlib.h>
       2  #include <stdint.h>
       3  #include <stdio.h>
       4  #include <string.h>
       5  
       6  #include <ISO_Fortran_binding.h>
       7  #include "dump-descriptors.h"
       8  
       9  struct s {
      10    int i;
      11    double d;
      12  };
      13  
      14  static long buf[5][4][3];
      15  
      16  /* External entry point.  */
      17  extern void ctest (void);
      18  
      19  void
      20  ctest (void)
      21  {
      22    int bad = 0;
      23    int status;
      24    CFI_CDESC_T(3) desc;
      25    CFI_cdesc_t *dv = (CFI_cdesc_t *) &desc;
      26    CFI_index_t ex[3], lb[3], ub[3];
      27    CFI_index_t sm;
      28  
      29    /* On entry, the base_addr member of the C descriptor shall be a null
      30       pointer.  */
      31    sm = sizeof (struct s);
      32    check_CFI_status ("CFI_establish",
      33  		    CFI_establish (dv, NULL, CFI_attribute_allocatable,
      34  				   CFI_type_struct, sm,
      35  				   0, NULL));
      36    check_CFI_status ("CFI_allocate",
      37  		    CFI_allocate (dv, NULL, NULL, 69));
      38    status = CFI_allocate (dv, NULL, NULL, 42);
      39    if (status == CFI_SUCCESS)
      40      {
      41        fprintf (stderr,
      42  	       "no error for CFI_allocate of already-allocated object\n");
      43        bad ++;
      44      }
      45    check_CFI_status ("CFI_deallocate",
      46  		    CFI_deallocate (dv));
      47  
      48    /* The attribute member of the C descriptor shall have a value of
      49       CFI_attribute_allocatable or CFI_attribute_pointer.  */
      50    ex[0] = 3;
      51    ex[1] = 4;
      52    ex[2] = 5;
      53    check_CFI_status ("CFI_establish",
      54  		    CFI_establish (dv, NULL, CFI_attribute_other,
      55  				   CFI_type_long, 0, 3, ex));
      56    lb[0] = 1;
      57    lb[1] = 2;
      58    lb[2] = 3;
      59    ub[0] = 10;
      60    ub[1] = 5;
      61    ub[2] = 10;
      62    sm = sizeof (long);
      63    status = CFI_allocate (dv, lb, ub, 20);
      64    if (status == CFI_SUCCESS)
      65      {
      66        fprintf (stderr,
      67  	       "no error for CFI_allocate of CFI_attribute_other object\n");
      68        bad ++;
      69      }
      70  
      71    /* dv shall be the address of a C descriptor describing the object.
      72       It shall have been allocated using the same mechanism as the
      73       Fortran ALLOCATE statement.  */
      74    ex[0] = 3;
      75    ex[1] = 4;
      76    ex[2] = 5;
      77    check_CFI_status ("CFI_establish",
      78  		    CFI_establish (dv, NULL, CFI_attribute_pointer,
      79  				   CFI_type_long, 0, 3, ex));
      80    status = CFI_deallocate (dv);
      81    if (status == CFI_SUCCESS)
      82      {
      83        fprintf (stderr,
      84  	       "no error for CFI_deallocate with null pointer\n");
      85        bad ++;
      86      }
      87  
      88    /* This variant is disabled.  In theory it should be possible for
      89       the memory allocator to easily check for pointers outside the
      90       heap region, but libfortran just calls free() which has no provision
      91       for returning an error, and there is no other standard C interface
      92       to check the validity of a pointer in the C heap either.  */
      93  #if 0  
      94    check_CFI_status ("CFI_establish",
      95  		    CFI_establish (dv, buf, CFI_attribute_pointer,
      96  				   CFI_type_long, 0, 3, ex));
      97    status = CFI_deallocate (dv);
      98    if (status == CFI_SUCCESS)
      99      {
     100        fprintf (stderr,
     101  	       "no error for CFI_deallocate with non-allocated pointer\n");
     102        bad ++;
     103      }
     104  #endif
     105  
     106    if (bad)
     107      abort ();
     108  }
     109