Function recursive definition error

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.

Hi @unterumarmung , thanks for flagging this up!

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.

-Andrzej

1 Like

@banach-space parsing and semantics target Fortran 2018. So maybe @klausler or @jeanPerier can comment or have a look.

2 Likes

Hello, I have an update!
The error stops reproducing when we change count of arguments of bar1 function from 2 to 1. This code compiles just fine:

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.

Hi, @jeanPerier! I’m actually in the process of making the patch. I’m testing my solution right now.

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.

Ok, I got it! Could you please share the link to Phabricator? I’d like to see how it was solved.

See ⚙ D122439 [flang] Fix cycle-catcher in procedure characterization