Hello, everyone!
I was experimenting with Flang compiler and I stumbled upon an error for the following code.
error: Semantic errors in b.f90
./a.f18.mod:4:10: error: Procedure 'foo' is recursively defined. Procedures in the cycle: 'bar1', 'foo1', 'foo2', 'foo'
function foo(x)
^^^
flang: in /home/d.dudkin/dev/gcp-41, flang-new failed with exit status 1: /home/d.dudkin/install/llvm-project/usr/local/bin/flang-new -fc1 -module-suffix .f18.mod -fdebug-unparse -fno-analyzed-objects-for-unparse -c b.f90
To be honest, I do not quite understand the problem and it seems like a bug.
gfortran and nvfortran compilers compile this code with no errors.
Is that a bug? If so, I’d like to fix it myself and I’ll appreciate any tips on how to fix it in best way.
To simplify this a bit, I suggest using flang-new (Flang’s compiler driver) instead of flang (a temporary bash wrapper script that calls flang-new). All this is rather confusing and should be resolved in time for LLVM 15 (i.e. flang-new will be renamed as flang). I tried documenting this here: llvm-project/FlangDriver.md at main · llvm/llvm-project · GitHub. Hopefully this will help clarify things!
Next, I was able to reproduce your issue like this:
flang-new -fsyntax-only a.f90
/flang-new -fsyntax-only b.f90
error: Semantic errors in b.f90
./a.mod:4:10: error: Procedure 'foo' is recursively defined. Procedures in the cycle: 'bar1', 'foo1', 'foo2', 'foo'
function foo(x)
I’m not a Fortran expert, so I also tried GFortran. I used the -std=f95 as LLVM Flang has no support for F2003 yet:
gfortran -fsyntax-only -std=f95 b.f90
b.f90:7:30:
7 | procedure(foo) :: foo1
| 1
Error: Fortran 2003: PROCEDURE statement at (1)
b.f90:8:31:
8 | procedure(foo) :: foo2
| 1
Error: Fortran 2003: PROCEDURE statement at (1)
b.f90:17:38:
17 | procedure(foo), pointer :: f1 => NULL()
| 1
Error: Fortran 2003: Procedure pointer at (1)
b.f90:18:38:
18 | procedure(foo), pointer :: f2 => NULL()
| 1
Error: Fortran 2003: Procedure pointer at (1)
b.f90:5:30:
5 | integer function bar1(foo1, foo2)
| 1
Error: Symbol ‘foo1’ at (1) has no IMPLICIT type
b.f90:5:36:
5 | integer function bar1(foo1, foo2)
| 1
Error: Symbol ‘foo2’ at (1) has no IMPLICIT type
b.f90:22:10:
22 | f1 => h%foo1
| 1
Error: Symbol ‘f1’ at (1) has no IMPLICIT type
b.f90:23:10:
23 | f2 => h%foo2
| 1
Error: Symbol ‘f2’ at (1) has no IMPLICIT type
So, GFortran implies that this is a F2003 module and LLVM Flang only support F95 ATM.
So, I’ve debugged the problem a little.
The problem is in Fortran::evaluate::characteristics::CharacterizeProcedure.
When this function is called on bar1 from the original example. And the function is recursively for each dummy argument with reusing same seenProcs container. And then, this function called again for the types of the arguments. And when the function called for the type of foo2, we get the error because we’ve already seen the foo procedure when analyzing the foo1 function.
Thanks for looking into this @unterumarmung, it seems like a bug to me. What you describe with seenProc indeed looks like a possible root cause. I believe @klausler might make a patch for this issue.
We ran into a similar problem in-house with a proprietary test suite. A fix is making its way to llvm-project/main, probably today. I’ve confirmed that it also fixes your problem.