I have a mixed Fortran ↔ C project, where the C code calls Fortran code.
The Fortran code depends on external routines (lnblnk, system, execute_command_line …).
Now the compiler appends an underscore leading to an unresolved symbol.
I cannot resolve this with -fno-underscoring, because after that the C code (which calls the routines from the Fortran code with underscores appended) leads to unresolved externals.
Is it possible to avoid the underscores for specific symbols or for symbols from external libraries?
This is a Python numpy.f2py scenario for explanation.
I can replace lnblnk with len_trim (the latter needs no resolution?), but i have not found a working replacement for system.
I made compile and link a success by replacing lnblnk → len_trim and system → execute_command_line. Are lnblnk and system not vailable wirh flang-new?
Hi thanks for your question.
execute_command_line
is a standard fortran instrinsic. lnblnk
and system
are non-standard intrinsics.
lnblnk
is not supported at all in flang. If you would like help adding support, please let me know.
system
and execute_command_line
should both be supported. Please could you give me a sample of some fortran code using system which reproduces this issue so that I can fix it.
I assumed there that you mean the fortran intrinsics with those names e.g. https://gcc.gnu.org/onlinedocs/gfortran/SYSTEM.html
If you would like to call C functions from fortran you need to declare them as bind(c)
with the correct C types in Fortran. This ensures the correct ABI is used for those calls and that the underscore is not added.
Thx for your response.
The line leading to unresolved system_ is
if (system(comline).ne.0) stop ‘DEATH ERROR counting columns’
Replacing this with
if (execute_command_line(comline).ne.0) stop ‘DEATH ERROR counting columns’
gives unresolved execute_command_line_, but
call execute_command_line(comline)
works.
I could now try call system, but what about the return code then?
Notes
- For practical purposes it works with len_trim and execute_command_line.
- I am not a Fortran expert.
- (half off topic) The (llvm based) Intel compiler has lnblnk (without underscore) in its runtimes, but the Fortran compiler generates lnblnk_. Do you have an idea how this is supposed to work?
Thanks for the information.
In Fortran sub routines (e.g. call system()
) and functions (system()
) are treated separately. It looks like we have a bug with the handling of the function form for system
. I will start work on a fix.
If you wanted to try call system()
you could pass the status as an optional intent(out) argument e.g.
integer :: status
call system(comline, status)
if (status .ne. 0) stop 'DEATH ERROR counting columns'
I don’t know anything about the Intel compiler. It might not have any relation to llvm-flang. Being llvm based can mean that a compiler just uses the llvm backend not that it is based on any of the languge frontends in the llvm-project repository.
Oversimplifying a bit, the frontend understands a particular language (e.g. clang, rustc, flang) then they share the backend which knows how to do language independent optimizations and instruction selection.
Thx again
- Fix for calling SYSTEM as a function: [flang] implement function form of SYSTEM intrinsic by tblah · Pull Request #117585 · llvm/llvm-project · GitHub
- Implementation of LNBLNK: [flang] Implement non-standard LNBLNK intrinsic by tblah · Pull Request #117589 · llvm/llvm-project · GitHub
This is fine, but what about calling execute_command_line as a function, this currently fails as well?
The Fortran standard describes execute_command_line
only as a subroutine.
16.9.83 EXECUTE_COMMAND_LINE(COMMAND[,WAIT,EXITSTAT, CMDSTAT,CMDMSG])
Description.Execute a command line.
Class. Subroutine.
gfortran documentation also lists it only as a subroutine.
I also did not see the following program work with a function like execute_command_line work with gfortran or ifx.
program test_exec
integer :: status
status = execute_command_line ("ls")
end program test_exec
I understand, thanks.
Hi, i have another question:
Would it be possible to merge this onto some llvm 19.x.y branch?
Thx Franz
I don’t think so. Only “bug fixes or very safe and critical performance improvements” are allowed. These patches would be categorized as implementing new features and so will not be available in a release until LLVM 20.
https://llvm.org/docs/HowToReleaseLLVM.html#release-patch-rules
OK thanks