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 /* For simplicity, point descriptors at a static buffer.  BUFSIZE should
10    be large enough for any of the standard types and we'll use DIM0 and DIM1
11    for array dimensions.  */
12 #define BUFSIZE 64
13 #define DIM0 3
14 #define DIM1 10
15 #define ARRAYBUFSIZE BUFSIZE * DIM0 * DIM1
16 static char *buf[ARRAYBUFSIZE] __attribute__ ((aligned (8)));
17 static CFI_index_t extents[] = {DIM0, DIM1};
18 
19 /* Magic number to use for elem_len field.  */
20 #define MAGIC_ELEM_LEN 20
21 
22 struct tc_info
23 {
24   CFI_type_t typecode;
25   char *name;
26   size_t size;
27 };
28 
29 static struct tc_info tc_table[] =
30 {
31   { CFI_type_signed_char, "CFI_type_signed_char", sizeof (signed char) },
32   { CFI_type_short, "CFI_type_short", sizeof (short) },
33   { CFI_type_int, "CFI_type_int", sizeof (int) },
34   { CFI_type_long, "CFI_type_long", sizeof (long) },
35   { CFI_type_long_long, "CFI_type_long_long", sizeof (long long) },
36   { CFI_type_size_t, "CFI_type_size_t", sizeof (size_t) },
37   { CFI_type_int8_t, "CFI_type_int8_t", sizeof (int8_t) },
38   { CFI_type_int16_t, "CFI_type_int16_t", sizeof (int16_t) },
39   { CFI_type_int32_t, "CFI_type_int32_t", sizeof (int32_t) },
40   { CFI_type_int64_t, "CFI_type_int64_t", sizeof (int64_t) },
41   { CFI_type_int_least8_t, "CFI_type_int_least8_t", sizeof (int_least8_t) },
42   { CFI_type_int_least16_t, "CFI_type_int_least16_t", sizeof (int_least16_t) },
43   { CFI_type_int_least32_t, "CFI_type_int_least32_t", sizeof (int_least32_t) },
44   { CFI_type_int_least64_t, "CFI_type_int_least64_t", sizeof (int_least64_t) },
45   { CFI_type_int_fast8_t, "CFI_type_int_fast8_t", sizeof (int_fast8_t) },
46   { CFI_type_int_fast16_t, "CFI_type_int_fast16_t", sizeof (int_fast16_t) },
47   { CFI_type_int_fast32_t, "CFI_type_int_fast32_t", sizeof (int_fast32_t) },
48   { CFI_type_int_fast64_t, "CFI_type_int_fast64_t", sizeof (int_fast64_t) },
49   { CFI_type_intmax_t, "CFI_type_intmax_t", sizeof (intmax_t) },
50   { CFI_type_intptr_t, "CFI_type_intptr_t", sizeof (intptr_t) },
51   { CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t", sizeof (ptrdiff_t) },
52   { CFI_type_float, "CFI_type_float", sizeof (float) },
53   { CFI_type_double, "CFI_type_double", sizeof (double) },
54   { CFI_type_long_double, "CFI_type_long_double", sizeof (long double) },
55   { CFI_type_float_Complex, "CFI_type_float_Complex",
56     sizeof (float _Complex) },
57   { CFI_type_double_Complex, "CFI_type_double_Complex",
58     sizeof (double _Complex) },
59   { CFI_type_long_double_Complex, "CFI_type_long_double_Complex",
60     sizeof (long double _Complex) },
61   { CFI_type_Bool, "CFI_type_Bool", sizeof (_Bool) },
62   { CFI_type_char, "CFI_type_char", sizeof (char) },
63   { CFI_type_cptr, "CFI_type_cptr", sizeof (void *) },
64   { CFI_type_struct, "CFI_type_struct", 0 },
65   { CFI_type_other, "CFI_type_other", -1 }
66 };
67 
68 int
test_array(struct tc_info * tc,void * ptr,CFI_attribute_t attr)69 test_array (struct tc_info *tc, void *ptr, CFI_attribute_t attr)
70 {
71   CFI_CDESC_T(2) desc;
72   CFI_cdesc_t *a = (CFI_cdesc_t *) &desc;
73   int bad = 0;
74   size_t elem_len;
75 
76   /* Initialize the descriptor to garbage values so we can confirm it's
77      properly initialized with good ones later.  */
78   memset (a, -1, sizeof(desc));
79 
80   check_CFI_status ("CFI_establish",
81 		    CFI_establish (a, ptr, attr, tc->typecode,
82 				   MAGIC_ELEM_LEN, 2, extents));
83 
84   /* elem_len is ignored unless type is CFI type struct, CFI type other,
85      or a character type.  */
86   if (tc->typecode == CFI_type_char
87       || tc->typecode == CFI_type_struct
88       || tc->typecode == CFI_type_other)
89     elem_len = MAGIC_ELEM_LEN;
90   else
91     elem_len = tc->size;
92 
93   if (a->elem_len != elem_len
94       || a->base_addr != ptr
95       || a->type != tc->typecode
96       || a->version != CFI_VERSION
97       || a->attribute != attr
98       || a->rank != 2
99       || (ptr &&
100 	  /* extents parameter is ignored if ptr is null */
101 	  (a->dim[0].lower_bound != 0
102 	   || a->dim[0].extent != DIM0
103 	   || a->dim[0].sm != elem_len
104 	   || a->dim[1].lower_bound != 0
105 	   || a->dim[1].extent != DIM1
106 	   || a->dim[1].sm != elem_len*DIM0)))
107     {
108       fprintf (stderr, "Bad array descriptor for %s:\n", tc->name);
109       dump_CFI_cdesc_t (a);
110       return 1;
111     }
112   return 0;
113 }
114 
115 /* External entry point.  */
116 extern void ctest_establish (void);
117 
118 void
ctest_establish(void)119 ctest_establish (void)
120 {
121   int ncodes = sizeof (tc_table) / sizeof (struct tc_info);
122   int i;
123   int bad = 0;
124 
125   for (i = 0; i < ncodes; i++)
126     {
127       bad += test_array (&tc_table[i], (void *)buf, CFI_attribute_other);
128       bad += test_array (&tc_table[i], NULL, CFI_attribute_allocatable);
129       bad += test_array (&tc_table[i], (void *)buf, CFI_attribute_pointer);
130     }
131   if (bad)
132     abort ();
133 }
134 
135