blob: 90f0b20fa457efe3009ffd88afd4e3d201a817f0 [file] [log] [blame]
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ISO_Fortran_binding.h>
extern void ctest_typecodes (void);
/* Do sanity checking on the CFI_type_* macros. In particular, make sure
that if two type codes have the same value, they represent objects of the
same size. */
struct tc_info
{
CFI_type_t typecode;
char *name;
size_t size;
int extension;
};
static struct tc_info tc_table[] =
{
/* Extension types.
Note there is no portable C equivalent type for CFI_type_ucs4_char type
(4-byte Unicode characters), so this is kind of hacky... */
#if CFI_type_int128_t > 0
{ CFI_type_int128_t, "CFI_type_int128_t",
sizeof (__int128), 1 },
{ CFI_type_int_least128_t, "CFI_type_int_least128_t",
sizeof (__int128), 1 },
{ CFI_type_int_fast128_t, "CFI_type_int_fast128_t",
sizeof (__int128), 1 },
#endif
#if CFI_type_ucs4_char > 0
{ CFI_type_ucs4_char, "CFI_type_ucs4_char", 4, 1 },
#endif
#if CFI_type_float128 > 0
{ CFI_type_float128, "CFI_type_float128",
sizeof (_Float128), 1 },
{ CFI_type_float128_Complex, "CFI_type_float128_Complex",
sizeof (_Float128 _Complex), 1 },
#endif
#if CFI_type_cfunptr > 0
{ CFI_type_cfunptr, "CFI_type_cfunptr",
sizeof (void (*)(void)), 1 },
#endif
/* Standard types. */
{ CFI_type_signed_char, "CFI_type_signed_char",
sizeof (signed char), 0, },
{ CFI_type_short, "CFI_type_short",
sizeof (short), 0 },
{ CFI_type_int, "CFI_type_int",
sizeof (int), 0 },
{ CFI_type_long, "CFI_type_long",
sizeof (long), 0 },
{ CFI_type_long_long, "CFI_type_long_long",
sizeof (long long), 0 },
{ CFI_type_size_t, "CFI_type_size_t",
sizeof (size_t), 0 },
{ CFI_type_int8_t, "CFI_type_int8_t",
sizeof (int8_t), 0 },
{ CFI_type_int16_t, "CFI_type_int16_t",
sizeof (int16_t), 0 },
{ CFI_type_int32_t, "CFI_type_int32_t",
sizeof (int32_t), 0 },
{ CFI_type_int64_t, "CFI_type_int64_t",
sizeof (int64_t), 0 },
{ CFI_type_int_least8_t, "CFI_type_int_least8_t",
sizeof (int_least8_t), 0 },
{ CFI_type_int_least16_t, "CFI_type_int_least16_t",
sizeof (int_least16_t), 0 },
{ CFI_type_int_least32_t, "CFI_type_int_least32_t",
sizeof (int_least32_t), 0 },
{ CFI_type_int_least64_t, "CFI_type_int_least64_t",
sizeof (int_least64_t), 0 },
{ CFI_type_int_fast8_t, "CFI_type_int_fast8_t",
sizeof (int_fast8_t), 0 },
{ CFI_type_int_fast16_t, "CFI_type_int_fast16_t",
sizeof (int_fast16_t), 0 },
{ CFI_type_int_fast32_t, "CFI_type_int_fast32_t",
sizeof (int_fast32_t), 0 },
{ CFI_type_int_fast64_t, "CFI_type_int_fast64_t",
sizeof (int_fast64_t), 0 },
{ CFI_type_intmax_t, "CFI_type_intmax_t",
sizeof (intmax_t), 0 },
{ CFI_type_intptr_t, "CFI_type_intptr_t",
sizeof (intptr_t), 0 },
{ CFI_type_ptrdiff_t, "CFI_type_ptrdiff_t",
sizeof (ptrdiff_t), 0 },
{ CFI_type_float, "CFI_type_float",
sizeof (float), 0 },
{ CFI_type_double, "CFI_type_double",
sizeof (double), 0 },
{ CFI_type_long_double, "CFI_type_long_double",
sizeof (long double), 0 },
{ CFI_type_float_Complex, "CFI_type_float_Complex",
sizeof (float _Complex), 0 },
{ CFI_type_double_Complex, "CFI_type_double_Complex",
sizeof (double _Complex), 0 },
{ CFI_type_long_double_Complex, "CFI_type_long_double_Complex",
sizeof (long double _Complex), 0 },
{ CFI_type_Bool, "CFI_type_Bool",
sizeof (_Bool), 0 },
{ CFI_type_char, "CFI_type_char",
sizeof (char), 0 },
{ CFI_type_cptr, "CFI_type_cptr",
sizeof (void *), 0 },
{ CFI_type_struct, "CFI_type_struct", 0, 0 },
{ CFI_type_other, "CFI_type_other", -1, 0, }
};
void
ctest_typecodes (void)
{
int ncodes = sizeof (tc_table) / sizeof (struct tc_info);
int i, j;
int bad = 0;
for (i = 0; i < ncodes; i++)
for (j = i + 1; j < ncodes; j++)
if (tc_table[i].typecode == tc_table[j].typecode
&& tc_table[i].typecode > 0
&& (tc_table[i].size != tc_table[j].size))
{
fprintf (stderr,
"type codes have the same value %d but different sizes\n",
(int) tc_table[i].typecode);
fprintf (stderr, " %s size %d\n",
tc_table[i].name, (int) tc_table[i].size);
fprintf (stderr, " %s size %d\n",
tc_table[j].name, (int) tc_table[j].size);
bad = 1;
}
/* TS29113 Section 8.3.4: The value for CFI_type_other shall be negative
and distinct from all other type specifiers. If a C type is not
interoperable with a Fortran type and kind supported by the
Fortran processor, its macro shall evaluate to a negative value.
Otherwise, the value for an intrinsic type shall be positive.
In the case of GCC, we expect that all the standard intrinsic
types are supported by both Fortran and C, so they should all be
positive except for CFI_type_other. Non-standard ones may have a
value -2. */
for (i = 0; i < ncodes; i++)
{
if (tc_table[i].typecode == CFI_type_other)
{
if (tc_table[i].typecode >= 0)
{
fprintf (stderr, "%s value %d is not negative\n",
tc_table[i].name, (int)tc_table[i].typecode);
bad = 1;
}
if (strcmp (tc_table[i].name, "CFI_type_other"))
{
fprintf (stderr, "%s has the same value %d as CFI_type_other\n",
tc_table[i].name, (int)CFI_type_other);
bad = 1;
}
}
else if (tc_table[i].typecode == -2 && tc_table[i].extension)
/* Unsupported extension type on this target; this is OK */
;
else if (tc_table[i].typecode <= 0)
{
fprintf (stderr, "%s value %d is not positive\n",
tc_table[i].name, (int)tc_table[i].typecode);
bad = 1;
}
}
if (bad)
abort ();
}