Le 10/06/2015 16:38, Jan Hubicka a écrit : >>> [jh@gcc2-power8 gcc]$ cat ../b.f90 >>> ! This testcase will abort if C_CHAR types are not interoperable >>> module lto_type_merge_test >>> use, intrinsic :: iso_c_binding >>> implicit none >>> >>> contains >>> function types_test1(V) bind(c) >>> USE, INTRINSIC :: ISO_C_BINDING >>> CHARACTER(C_CHAR) :: types_test1 >>> CHARACTER(C_CHAR), VALUE :: V >>> types_test1 = V >>> end function types_test1 >>> end module lto_type_merge_test >>> >>> [jh@gcc2-power8 gcc]$ cat ../a.c >>> extern unsigned char types_test1 (char v); >>> void >>> main () >>> { >>> if (types_test1 ('a') != 'a') >>> __builtin_abort (); >>> return 0; >>> } >>> >>> As my fortran-fu goes, i think this testcase is correct. Fortran FE however >>> builds types_test1 as a function return char but taking the array of size >>> of 1 >>> as a parameter. >> C_CHAR is a named constant of value 1 (the number of bytes of a char), >> and character(foo) declares a string of length foo and default kind >> (which is 1 for character types). >> So it is expected that the argument is an array. > > I see, what is the reason for assymetry for return value to not be array in > this case?
There is this in gfc_sym_type: if (sym->ts.type == BT_CHARACTER && ((sym->attr.function && sym->attr.is_bind_c) || (sym->attr.result && sym->ns->proc_name && sym->ns->proc_name->attr.is_bind_c) || (sym->ts.deferred && (!sym->ts.u.cl || !sym->ts.u.cl->backend_decl)))) type = gfc_character1_type_node; else type = gfc_typenode_for_spec (&sym->ts); And gfc_character1_type_node is defined as a plain char, it seems. I don't know about the reason for either. > >> If you want to declare a single character, you have to use an integer of >> kind 1. >> types_test1's result and v should have type integer(c_char), I think. > > I will fix the testcase accordingly. I basicallly copied what is in table > 15.2 of the Fortran 2008 draft that explicitely lists Fortran type CHARACTER > if kind C_CHAR compatible with "char". On the other hand there are no examples > in the standard that would suggest that this should work this way. > It only shows stuff like > CHARACTER(KIND=C_CHAR), DIMENSION(*) :: IN, OUT > which corresponds to char [] > > Is my testcase supposed to work if I simply add KIND= before "C_CHAR" > I have had a look at the table and the text around, and first I should correct myself. C_CHAR is 1, C_SIGNED_CHAR is 1, and the default values for len= and kind= are 1 as well. So, even if CHARACTER(KIND=C_CHAR) is what should be used as it's not dependent on the implementation's default kind choice, it boils down to the same as CHARACTER(C_CHAR), namely CHARACTER(len=1, kind=1) actually. And about the line saying CHARACTER(KIND=C_CHAR) interoperable with char in table 15.2: You're right, while I would myself prefer to use an INTEGER(KIND=C_SIGNED_CHAR) type, CHARACTER(KIND=C_CHAR) should be supported as well. That means that char should be compatible with char[1], I think. You said there is no guarantee they are passed the same way? > If you can look at the other c-bind testcases I produced, I would really > appreachiate that. I have looked at: https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00693.html https://gcc.gnu.org/ml/gcc-patches/2015-06/msg00713.html I saw nothing wrong with the tests. Avoiding character interoperability avoids most of the pain. ;-) Mikael