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.