This is an archive of the discontinued LLVM Phabricator instance.

[flang] Handle BINC(C) variables and add TODO for corner cases
ClosedPublic

Authored by clementval on Jun 22 2022, 7:06 AM.

Details

Summary
  • BIND(C) was ignored in lowering for objects (it can be used on

module and common blocks): use the bind name as the fir.global name.

  • When an procedure is declared BIND(C) indirectly via an interface, it should have a BIND(C) name. This was not the case because GetBindName()/bindingName() return nothing in this case: detect this case in mangler.cpp and use the symbol name.

Add TODOs for corner cases:

  • BIND(C) module variables may be initialized on the C side. This does not fit well with the current linkage strategy. Add a TODO until this is revisited.
  • BIND(C) internal procedures should not have a binding label (see Fortran 2018 section 18.10.2 point 2), yet we currently lower them as if they were BIND(C) external procedure. I think this and the indirect interface case should really be handled by symbol.GetBindName instead of adding more logic in lowering to deal with this case: add a TODO.

This patch is part of the upstreaming effort from fir-dev branch.

Co-authored-by: Jean Perier <jperier@nvidia.com>

Diff Detail

Event Timeline

clementval created this revision.Jun 22 2022, 7:06 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptJun 22 2022, 7:06 AM
Herald added a subscriber: mehdi_amini. · View Herald Transcript
clementval requested review of this revision.Jun 22 2022, 7:06 AM

Emit fatal error

klausler accepted this revision.Jun 22 2022, 11:44 AM
This revision is now accepted and ready to land.Jun 22 2022, 11:44 AM
peixin added a subscriber: peixin.Jun 22 2022, 7:12 PM

@clementval Is there any BIND(C) related patch not upstreamed? I am tring to use LLVM Flang to build openmpi. The fir-dev fails due to the incorrect external procedure name. So, now I use llvm main. It still fails and I am analyzing. Just want to confirm no BIND(C) related patch left in fir-dev.

BIND(C) internal procedures should not have a binding label (see Fortran 2018 section 18.10.2 point 2), yet we currently lower them as if they were BIND(C) external procedure. I think this and the indirect interface case should really be handled by symbol.GetBindName instead of adding more logic in lowering to deal with this case: add a TODO.

I took a look at gfortran and ifort. If with NAME= specified for the following case, both gfortran and ifort report error.

program main
contains
  subroutine sub() bind(c)
    integer :: i = 1
    print *, i
  end
end

For gfortran, the sub is optimized out when compiling to executable file. For ifort:

$ ifort test.f90 && nm a.out | grep sub
0000000000477080 T __subq
0000000000477020 t subq_abs
0000000000477ef0 t subq_abs.A
0000000000476760 t subq_abs.L

Then I tried the following case:

$ cat internal.f90 
program main
  integer :: i = 1
  call sub()
  call c_func()
  print *, i
contains
  subroutine sub() bind(c)
    i = i + 1
  end
end
$ cat c_code.c 
void __subq();
void c_func_() {
  __subq();
}
$ gfortran internal.f90 -c
$ gcc c_code.c -c
$ gfortran internal.o c_code.o 
/usr/bin/ld: c_code.o: in function `c_func_':
c_code.c:(.text+0x8): undefined reference to `__subq'
collect2: error: ld returned 1 exit status
$ nm internal.o 
                 U c_func_
                 U _gfortran_set_args
                 U _gfortran_set_options
                 U _gfortran_st_write
                 U _gfortran_st_write_done
                 U _gfortran_transfer_integer_write
0000000000000000 d i.2774
00000000000000ac T main
0000000000000030 t MAIN__
0000000000000010 r options.1.2781
0000000000000000 t sub.2772
$ ifort internal.f90 -c
$ icc c_code.c -c
$ ifort internal.o c_code.o 
$ ./a.out
forrtl: severe (174): SIGSEGV, segmentation fault occurred

So, I think it's safe to reject internal procedure with BIND(C) attribute and need not to worry that GCC and ICC can support this, which should be done in https://github.com/llvm/llvm-project/blob/1dd2c93a660cd5de0769ff88634fe149904caa17/flang/lib/Semantics/check-declarations.cpp#L1883.

@clementval Is there any BIND(C) related patch not upstreamed? I am tring to use LLVM Flang to build openmpi. The fir-dev fails due to the incorrect external procedure name. So, now I use llvm main. It still fails and I am analyzing. Just want to confirm no BIND(C) related patch left in fir-dev.

There might be some more patches to be upstream. I do not have a clear view of what exact features/bug fixes are left to be upstreamed. I'm going by diffs and I'll have a better view early next week.

@clementval Is there any BIND(C) related patch not upstreamed? I am tring to use LLVM Flang to build openmpi. The fir-dev fails due to the incorrect external procedure name. So, now I use llvm main. It still fails and I am analyzing. Just want to confirm no BIND(C) related patch left in fir-dev.

There might be some more patches to be upstream. I do not have a clear view of what exact features/bug fixes are left to be upstreamed. I'm going by diffs and I'll have a better view early next week.

Great. Thanks a lot.