https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77278

--- Comment #28 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
(In reply to Jan Hubicka from comment #27)
> > 
> > I think that's reasonably easy to do for LTO.  We'd want to keep
> > the default boolean_type_node size BOOLEAN_TYPEs separate but
> > can glob larger ones with integer types in the canonical type
> > merging.  We can probably do the same in non-LTO but that might
> > not be required.
> 
> Yes, we can glob other sizes of bool into integers and that should
> not affect non-fortran languages where truth comes in only one size.
> It would be bit inconsistent in a way that logical sized same way
> as C bool will bind to C _Bool type and others will bind to integer
> types of corresponding sizes.

That would be excellent.  It would also solve a problem with
non-standard interoperability (which people used before there
was the standard version, and which continues to be used
to this day, for example in LAPACK or BLAS).

The old code passes a standard LOGICAL to a C routine by reference,
but the C side can only use an int pointer.

> The Fortran 2003 language draft has section on interoperability of
> C and Fortran language:
> https://j3-fortran.org/doc/year/10/10-007.pdf
> Which says that fortran language C_BOOL should interoperate with _Bool.
> Why libgfortran API functions which dispatch into C code are not
> declared with C_BOOL rather than the integer sized logical?

History.  The library implementation was started long before the
standard C interface. And when we implemented the BACK intrinsic,
passing it as a C_BOOL was simply not discussed.

If we ever rewrite our ABI (again), I think it would make sense to
pass all scalar LOGICAL arguments via scalar.

> I wrote some testcases for LTO C and fortran types interoperatibility
> (gfortran.dg/lto/bind_c*)
> Since my Fortran-fu is limited, they may not be complete. It would be
> very useful to look into them and see if everything important is
> tested and also that we have testcase for all cases we want to support
> in addition to stadnard (like this one it seems) with some rationale
> in them for future reference.

One thing that should work is (according to the convention that
people use, and also to what we're using in libgfortran):

$ cat logical_f.f90
program main
  logical (kind=1) :: l1
  logical (kind=2) :: l2
  logical (kind=4) :: l4
  logical (kind=8) :: l8
  logical (kind=16) :: l16

  l1 = .true.
  l2 = .true.
  l4 = .true.
  l8 = .true.
  call logical_c (l1, l2, l4, l8, l16)
  if (l1 .or. l2 .or. l4 .or. l8 .or. l16) stop 1
end program main

subroutine foo(l1, l2, l4, l8, l16)
  logical (kind=1) :: l1
  logical (kind=2) :: l2
  logical (kind=4) :: l4
  logical (kind=8) :: l8
  logical (kind=16) :: l16

  l1 = .false.
  l2 = .false.
  l4 = .false.
  l8 = .false.
  l16 = .false.
end subroutine foo

$ cat logical_c.c
void logical_c_ (_Bool *l1, short *l2, int *l4, long *l8, long long *l16)
{
  foo_ (l1, l2, l4, l8, l16);
}

This would be a big first step in making things compatible.

Another test case which currently works, and where it would
be important that it keeps working, is

$ cat character_f.f90
program main
  character (len=10) :: a
  a = ''
  call foo(a)
  if (a /= '0123456789') stop 1
end program main

subroutine bar (a)
  character (len=*), intent(inout) :: a
  if (len(a) /= 10) stop 2
  if (a /= 'ABCDEFGHIJ') stop 3
  a = '0123456789'
end subroutine bar
$ cat character_c.c
#include <stddef.h>
#include <string.h>

void bar_ (char *a, size_t a_len);

void foo_ (char *a, size_t a_len)
{
  memcpy (a, "ABCDEFGHIJ", 10);
  bar_ (a, 10);
}

A really large positive effect would be that we could then really
tell people to use -flto to detect broken C / Fortran bindings.
Unfortunately, there are very many out there, see PR 90329.

Reply via email to