Bind(c) and descriptor corruption

José Rui Faustino de Sousa jrfsousa@gmail.com
Sun Nov 24 13:10:00 GMT 2019


Hi Tobias,

On 24/11/19 10:11, Tobias Burnus wrote:
> Try compiling with -fdump-tree-original to show in pseudo-C format how 
> the generated code looks like. (The dump does not show all data, but 
> helps with debugging/understanding the code).
> 

That is how I bumped into it, only using the gimple tree instead.

Walking trough the code with gdb seemed to confirm it.

> As everything is both in the compiler itself and in the run-time library 
> adapted for the gfortran's Fortran ("gfc") descriptor: If you write a 
> procedure with C binding in Fortran, the descriptor is converted back to 
> gfc descriptor at the begin of the procedure (and needs to be converted 
> back to CFI at the end or when calling another bind-C procedure).
> 

Yes the descriptors are converted before entering the bind(c) 
procedures, but inside a bind(c) procedure it should be done the other 
way around.

Cut from a very simple code:

bind3_p () ! <- the "main" program
{
   [...]
   integer(kind=4) val;

   {
     struct array00_integer(kind=4) desc.3;
     void * cfi.4;

     [...initialize descriptors...]
     _gfortran_gfc_desc_to_cfi_desc (&cfi.4, &desc.3);
     [...]
     middle_b (cfi.4); ! <- bind(c) procedure
[...]

middle_b (struct array15_unknown & val) ! <- bind(c) procedure the CFI 
descriptor seems to be cast to a GFC descriptor
{
   final_f ((struct array15_unknown *) val); ! <- "fortran" procedure 
receiving an unconverted CFI descriptor
   {
     void * cfi.2;

     [...initialize descriptors...]
     _gfortran_gfc_desc_to_cfi_desc (&cfi.2, (struct array15_unknown *) 
val); ! <- double conversion
     [...]
     final_b (cfi.2); ! <- bind(c) procedure
[...]

Walking trough the code using gdb looking at the addresses and using 
some casts seemed to confirm that this what is happening.

> At least for pointers/allocatable arguments, some of the conversion 
> calls are missing. See https://gcc.gnu.org/PR92189
> 

Yes, that is exactly what I was noticing.

> I think the biggest difference is that gfc stores lower_bound and 
> upper_bound while CFI has lower_bound and extent. As soon as lower_bound 
> != 0, this causes problems. Additionally, there are some ordering 
> differences for the type. See conversion functions for detail.
> 

Exactly, the address is not affected but everything else gets more or 
less messed up. There seems to be already some code in place to patch it 
up but it seems unnecessary and, in this case, obscuring what is going on.

Best regards,
José Rui



More information about the Fortran mailing list