Duplicate symbol for function inside and outside module

Hi,

consider this test code

subroutine foo_bar()
end subroutine

module foo 
   public :: bar 
contains
   subroutine bar()
   end subroutine
end module foo 

program test
   use foo, only : bar 
   call bar();
   call foo_bar();
end program test

It fails with the following error message

error: /home/cweiss/build/pgi_sdk/Linux_x86_64/22.3/compilers/share/llvm/bin/llc: /tmp/nvfortranZnaBzbR8MXno.ll:16:23: error: invalid redefinition of function 'foo_bar_'

The issue is that the function bar inside the module foo gets registered in the symbol table as foo_bar. This is the same name which is used for the subroutine outside of the module. I cannot see a reason why this code might be invalid according to the Fortran standard.

As a side note, gfortran compiles this code. The module-associated function is called foo_MOD_bar, which separates it from foo_bar.

Best regards,
Christian

Hi Christian,

I can talk to our managers but it’s unlikely that we would change how we do the module function naming. It’s how we’ve always done this naming as far back as the initial PGI F90 implementation in the early 1990s. Perhaps they could have had more forethought, but changing the naming convention now would break compatibility and be extremely disruptive to our users.

Also, it’s extremely rare that anyone to encounter this issue (most folks don’t mix F77 and F90 style APIs), and is very easy to work around (either change the name or use BIND(C) to change the underlying symbol name), this is why I doubt they’ll want to make this change without a compelling reason.

-Mat

After playing around with this symbol name collision a little bit I found out that it is not related to mixed F77 and F90 APIs. Even if everything is F90 as in the following code, the problem remains:

MODULE foo 
   PUBLIC :: foo_bar
CONTAINS
   SUBROUTINE foo_bar()
   END SUBROUTINE
END MODULE foo 

MODULE foo_foo
   PUBLIC :: bar 
CONTAINS
   SUBROUTINE bar()
   END SUBROUTINE bar 
END MODULE foo_foo

PROGRAM test
   USE foo, ONLY : foo_bar
   USE foo_foo, ONLY: bar 
   CALL foo_bar()
   CALL bar()
END PROGRAM test

Hi Mat,

thanks for the quick reply. I understand that fixing this issue is very involved and has a low priority. I just wanted to point it out, in case that you might find it interesting. For me, it’s not an important issue that needs resolution.

Best regards,
Christian