Bug 87127 - External function not recognised from within an associate block
Summary: External function not recognised from within an associate block
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 8.0
: P4 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: associate
  Show dependency treegraph
 
Reported: 2018-08-28 11:48 UTC by Paul Thomas
Modified: 2023-06-01 13:52 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-10-05 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Thomas 2018-08-28 11:48:31 UTC
Posted on: https://groups.google.com/forum/#!topic/comp.lang.fortran/Jc_3vZeATdU

function exfunc(i)
implicit none
integer :: exfunc,i
exfunc = 2*i
end function

! contents of test.f90
program test
implicit none
integer :: exfunc,i
integer,parameter :: array(2)=[6,7]
associate(i=>array(1))
write(*,*) exfunc(i)
end associate
end program 

produces

 write(*,*) exfunc(i)
          1
Error: ‘exfunc’ at (1) is not a function

Removing the associate block, invoking 'exfunc' outside it or declaring it explicitly to be a function all remove the error.

Other brands compile the testcase without error.

At first glance, it seems that resolution of symbols in the main program is occurring without taking the associate block into account and that this is resolved afterwards.
Comment 1 Jürgen Reuter 2018-10-05 10:29:48 UTC
Present since at least version 5.4. It is still present in the very recent trunk (r264725).
Comment 2 Dominique d'Humieres 2018-10-05 10:36:02 UTC
> Present since at least version 5.4. It is still present in the very
> recent trunk (r264725).

Also present in 4.8 and 4.9.
Comment 3 Tobias Burnus 2018-10-17 22:43:11 UTC
Variant:

program test
  implicit none
  integer :: exfunc, i
  call foo()
contains
  subroutine foo()
    write(*,*) exfunc(i)
  end subroutine foo
end program


In primary.c's gfc_match_rvalue(), we try to parse a symbol in several ways – if everything fails:

      /* Give up, assume we have a function.  */
      gfc_get_sym_tree (name, NULL, &symtree, false);   /* Can't fail */
      sym = symtree->n.sym;
      e->expr_type = EXPR_FUNCTION;
      if (!sym->attr.function
          && !gfc_add_function (&sym->attr, sym->name, NULL))

This sets both attr.flavor = FL_PROCEDURE and attr.function = 1.

If we call "exfunc" in "program test", everything is fine.

However, if we call "exfunc" in a block (associate) or a contained procedure, we are in a different namespace.

In the local namespace, the symbol is FL_PROCEDURE with attr.function.
In the parent namespace, the symbol has will be to FL_VARIABLE.

In resolve_symbol, one tries to resolve the symbol:
  if (sym->attr.flavor == FL_UNKNOWN
      || (sym->attr.flavor == FL_PROCEDURE && !sym->attr.intrinsic
          && !sym->attr.generic && !sym->attr.external
          && sym->attr.if_source == IFSRC_UNKNOWN
          && sym->ts.type == BT_UNKNOWN))
    {

Thus, one ends up with a symbol without attr.function.
Comment 4 paul.richard.thomas@gmail.com 2018-10-18 07:28:26 UTC
Hi Tobias,

I have been looking at this one on and off. I think that blocks should
be resolved in the same way as contained procedures; I tried adding
them to the parent contained list (the night before last) and ended up
with segfaults on cleanup. This is easily fixed but I just did not
have time.

Cheers

Paul

On Wed, 17 Oct 2018 at 23:43, burnus at gcc dot gnu.org
<gcc-bugzilla@gcc.gnu.org> wrote:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87127
>
> Tobias Burnus <burnus at gcc dot gnu.org> changed:
>
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |burnus at gcc dot gnu.org
>
> --- Comment #3 from Tobias Burnus <burnus at gcc dot gnu.org> ---
> Variant:
>
> program test
>   implicit none
>   integer :: exfunc, i
>   call foo()
> contains
>   subroutine foo()
>     write(*,*) exfunc(i)
>   end subroutine foo
> end program
>
>
> In primary.c's gfc_match_rvalue(), we try to parse a symbol in several ways –
> if everything fails:
>
>       /* Give up, assume we have a function.  */
>       gfc_get_sym_tree (name, NULL, &symtree, false);   /* Can't fail */
>       sym = symtree->n.sym;
>       e->expr_type = EXPR_FUNCTION;
>       if (!sym->attr.function
>           && !gfc_add_function (&sym->attr, sym->name, NULL))
>
> This sets both attr.flavor = FL_PROCEDURE and attr.function = 1.
>
> If we call "exfunc" in "program test", everything is fine.
>
> However, if we call "exfunc" in a block (associate) or a contained procedure,
> we are in a different namespace.
>
> In the local namespace, the symbol is FL_PROCEDURE with attr.function.
> In the parent namespace, the symbol has will be to FL_VARIABLE.
>
> In resolve_symbol, one tries to resolve the symbol:
>   if (sym->attr.flavor == FL_UNKNOWN
>       || (sym->attr.flavor == FL_PROCEDURE && !sym->attr.intrinsic
>           && !sym->attr.generic && !sym->attr.external
>           && sym->attr.if_source == IFSRC_UNKNOWN
>           && sym->ts.type == BT_UNKNOWN))
>     {
>
> Thus, one ends up with a symbol without attr.function.
>
> --
> You are receiving this mail because:
> You reported the bug.
Comment 5 Jürgen Reuter 2019-03-29 23:08:13 UTC
Paul, would be cool to get back to this one! ;)
Comment 6 paul.richard.thomas@gmail.com 2019-03-30 09:23:28 UTC
Hi Juergen,

Noted - as it happens, I have an hour or so right now :-)

Cheers

Paul

On Fri, 29 Mar 2019 at 23:08, juergen.reuter at desy dot de
<gcc-bugzilla@gcc.gnu.org> wrote:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87127
>
> --- Comment #5 from Jürgen Reuter <juergen.reuter at desy dot de> ---
> Paul, would be cool to get back to this one! ;)
>
> --
> You are receiving this mail because:
> You reported the bug.
Comment 7 Paul Thomas 2019-04-24 07:28:13 UTC
Author: pault
Date: Wed Apr 24 07:27:42 2019
New Revision: 270532

URL: https://gcc.gnu.org/viewcvs?rev=270532&root=gcc&view=rev
Log:
2019-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/87127
	* resolve.c (check_host_association): If an external function
	is typed but not declared explicitly to be external, change the
	old symbol from a variable to an external function.

2019-04-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/87127
	* gfortran.dg/external_procedures_4.f90: New test.

Added:
    branches/gcc-8-branch/gcc/testsuite/gfortran.dg/external_procedures_4.f90
Modified:
    branches/gcc-8-branch/gcc/fortran/ChangeLog
    branches/gcc-8-branch/gcc/fortran/resolve.c
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
Comment 8 Vladimir Fuka 2021-03-01 17:06:37 UTC
I see a comment but at the same time the status is NEW. What is the actual status?

In any case, the issue still exists in GCC 11. https://stackoverflow.com/questions/66424857/dlantr-at-1-is-not-a-function/66425244?noredirect=1#comment117432549_66425244
Comment 9 Vladimir Fuka 2021-03-01 17:58:04 UTC
I see now, it was fixed on the 8 branch, but not on the trunk! It ought to be applied at least to the 12.
Comment 10 GCC Commits 2023-03-20 06:14:15 UTC
The master branch has been updated by Paul Thomas <pault@gcc.gnu.org>:

https://gcc.gnu.org/g:5889c7bd46a45dc07ffb77ec0d698e18e0b99840

commit r13-6758-g5889c7bd46a45dc07ffb77ec0d698e18e0b99840
Author: Paul Thomas <pault@gcc.gnu.org>
Date:   Mon Mar 20 06:13:54 2023 +0000

    Fortran: Allow external function from in an associate block [PR87127]
    
    2023-03-20  Paul Thomas  <pault@gcc.gnu.org>
    
    gcc/fortran
            PR fortran/87127
            * resolve.cc (check_host_association): If an external function
            is typed but not declared explicitly to be external, change the
            old symbol from a variable to an external function.
    
    gcc/testsuite/
            PR fortran/87127
            * gfortran.dg/external_procedures_4.f90: New test.
Comment 11 GCC Commits 2023-03-20 06:23:43 UTC
The releases/gcc-12 branch has been updated by Paul Thomas <pault@gcc.gnu.org>:

https://gcc.gnu.org/g:9ccf471f8cc7341984f6613247f01d8ecfcb7ad5

commit r12-9295-g9ccf471f8cc7341984f6613247f01d8ecfcb7ad5
Author: Paul Thomas <pault@gcc.gnu.org>
Date:   Mon Mar 20 06:23:29 2023 +0000

    Fortran: Allow external function from in an associate block [PR87127]
    
    2023-03-20  Paul Thomas  <pault@gcc.gnu.org>
    
    gcc/fortran
            PR fortran/87127
            * resolve.cc (check_host_association): If an external function
            is typed but not declared explicitly to be external, change the
            old symbol from a variable to an external function.
    
    gcc/testsuite/
            PR fortran/87127
            * gfortran.dg/external_procedures_4.f90: New test.
Comment 12 Paul Thomas 2023-06-01 13:52:05 UTC
I think that this one can be closed now.

Paul