/gcc/testsuite/gfortran.dg/ISO_Fortran_binding_1.c

https://gitlab.com/4144/gcc · C · 201 lines · 160 code · 33 blank · 8 comment · 35 complexity · fe54b6b6c4df6ffbc3faeb4350138a26 MD5 · raw file

  1. /* Test F2008 18.5: ISO_Fortran_binding.h functions. */
  2. #include "../../../libgfortran/ISO_Fortran_binding.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <complex.h>
  6. /* Test the example in F2008 C.12.9: Processing assumed-shape arrays in C,
  7. modified to use CFI_address instead of pointer arithmetic. */
  8. int elemental_mult_c(CFI_cdesc_t * a_desc, CFI_cdesc_t * b_desc,
  9. CFI_cdesc_t * c_desc)
  10. {
  11. CFI_index_t idx[2];
  12. int *res_addr;
  13. int err = 1; /* this error code represents all errors */
  14. if (a_desc->rank == 0)
  15. {
  16. err = *(int*)a_desc->base_addr;
  17. *(int*)a_desc->base_addr = 0;
  18. return err;
  19. }
  20. if (a_desc->type != CFI_type_int
  21. || b_desc->type != CFI_type_int
  22. || c_desc->type != CFI_type_int)
  23. return err;
  24. /* Only support two dimensions. */
  25. if (a_desc->rank != 2
  26. || b_desc->rank != 2
  27. || c_desc->rank != 2)
  28. return err;
  29. for (idx[0] = 0; idx[0] < a_desc->dim[0].extent; idx[0]++)
  30. for (idx[1] = 0; idx[1] < a_desc->dim[1].extent; idx[1]++)
  31. {
  32. res_addr = CFI_address (a_desc, idx);
  33. *res_addr = *(int*)CFI_address (b_desc, idx)
  34. * *(int*)CFI_address (c_desc, idx);
  35. }
  36. return 0;
  37. }
  38. int deallocate_c(CFI_cdesc_t * dd)
  39. {
  40. return CFI_deallocate(dd);
  41. }
  42. int allocate_c(CFI_cdesc_t * da, CFI_index_t lower[], CFI_index_t upper[])
  43. {
  44. int err = 1;
  45. CFI_index_t idx[2];
  46. int *res_addr;
  47. if (CFI_allocate(da, lower, upper, 0)) return err;
  48. for (idx[0] = 0; idx[0] < da->dim[0].extent; idx[0]++)
  49. for (idx[1] = 0; idx[1] < da->dim[1].extent; idx[1]++)
  50. {
  51. res_addr = CFI_address (da, idx);
  52. *res_addr = (int)((idx[0] + da->dim[0].lower_bound)
  53. * (idx[1] + da->dim[1].lower_bound));
  54. }
  55. return 0;
  56. }
  57. int establish_c(CFI_cdesc_t * desc)
  58. {
  59. typedef struct {double x; double _Complex y;} t;
  60. int err;
  61. CFI_index_t idx[1], extent[1];
  62. t *res_addr;
  63. double value = 1.0;
  64. double complex z_value = 0.0 + 2.0 * I;
  65. extent[0] = 10;
  66. err = CFI_establish((CFI_cdesc_t *)desc,
  67. malloc ((size_t)(extent[0] * sizeof(t))),
  68. CFI_attribute_pointer,
  69. CFI_type_struct,
  70. sizeof(t), 1, extent);
  71. for (idx[0] = 0; idx[0] < extent[0]; idx[0]++)
  72. {
  73. res_addr = (t*)CFI_address (desc, idx);
  74. res_addr->x = value++;
  75. res_addr->y = z_value * (idx[0] + 1);
  76. }
  77. return err;
  78. }
  79. int contiguous_c(CFI_cdesc_t * desc)
  80. {
  81. return CFI_is_contiguous(desc);
  82. }
  83. float section_c(int *std_case, CFI_cdesc_t * source, int *low, int *str)
  84. {
  85. CFI_index_t idx[CFI_MAX_RANK], lower[CFI_MAX_RANK],
  86. strides[CFI_MAX_RANK], upper[CFI_MAX_RANK];
  87. CFI_CDESC_T(1) section;
  88. int ind;
  89. float *ret_addr;
  90. float ans = 0.0;
  91. /* Case (i) from F2018:18.5.5.7. */
  92. if (*std_case == 1)
  93. {
  94. lower[0] = (CFI_index_t)low[0];
  95. strides[0] = (CFI_index_t)str[0];
  96. ind = CFI_establish((CFI_cdesc_t *)&section, NULL, CFI_attribute_other,
  97. CFI_type_float, 0, 1, NULL);
  98. if (ind) return -1.0;
  99. ind = CFI_section((CFI_cdesc_t *)&section, source, lower, NULL, strides);
  100. if (ind) return -2.0;
  101. /* Sum over the section */
  102. for (idx[0] = 0; idx[0] < section.dim[0].extent; idx[0]++)
  103. ans += *(float*)CFI_address ((CFI_cdesc_t*)&section, idx);
  104. return ans;
  105. }
  106. else if (*std_case == 2)
  107. {
  108. int ind;
  109. lower[0] = source->dim[0].lower_bound;
  110. upper[0] = source->dim[0].lower_bound + source->dim[0].extent - 1;
  111. strides[0] = str[0];
  112. lower[1] = upper[1] = source->dim[1].lower_bound + low[1] - 1;
  113. strides[1] = 0;
  114. ind = CFI_establish((CFI_cdesc_t *)&section, NULL, CFI_attribute_other,
  115. CFI_type_float, 0, 1, NULL);
  116. if (ind) return -1.0;
  117. ind = CFI_section((CFI_cdesc_t *)&section, source,
  118. lower, upper, strides);
  119. if (ind) return -2.0;
  120. /* Sum over the section */
  121. for (idx[0] = 0; idx[0] < section.dim[0].extent; idx[0]++)
  122. ans += *(float*)CFI_address ((CFI_cdesc_t*)&section, idx);
  123. return ans;
  124. }
  125. return 0.0;
  126. }
  127. double select_part_c (CFI_cdesc_t * source)
  128. {
  129. typedef struct {
  130. double x; double _Complex y;
  131. } t;
  132. CFI_CDESC_T(2) component;
  133. CFI_cdesc_t * comp_cdesc = (CFI_cdesc_t *)&component;
  134. CFI_index_t extent[] = {10,10};
  135. CFI_index_t idx[] = {4,0};
  136. double ans = 0.0;
  137. int size;
  138. (void)CFI_establish(comp_cdesc, NULL, CFI_attribute_other,
  139. CFI_type_double_Complex, sizeof(double _Complex),
  140. 2, extent);
  141. (void)CFI_select_part(comp_cdesc, source, offsetof(t,y), 0);
  142. /* Sum over comp_cdesc[4,:] */
  143. size = comp_cdesc->dim[1].extent;
  144. for (idx[1] = 0; idx[1] < size; idx[1]++)
  145. ans += cimag (*(double _Complex*)CFI_address ((CFI_cdesc_t*)comp_cdesc,
  146. idx));
  147. return ans;
  148. }
  149. int setpointer_c(CFI_cdesc_t * ptr, int lbounds[])
  150. {
  151. CFI_index_t lower_bounds[] = {lbounds[0],lbounds[1]};
  152. int ind;
  153. ind = CFI_setpointer(ptr, ptr, lower_bounds);
  154. return ind;
  155. }
  156. int assumed_size_c(CFI_cdesc_t * desc)
  157. {
  158. int res;
  159. res = CFI_is_contiguous(desc);
  160. if (!res)
  161. return 1;
  162. if (desc->rank)
  163. res = 2 * (desc->dim[desc->rank-1].extent
  164. != (CFI_index_t)(long long)(-1));
  165. else
  166. res = 3;
  167. return res;
  168. }