Bug 33897 - Incorrect host association in module
Summary: Incorrect host association in module
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: rejects-valid
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2007-10-25 16:46 UTC by Michael Richmond
Modified: 2007-10-31 09:59 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.0.4
Known to fail:
Last reconfirmed: 2007-10-26 09:36:40


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Richmond 2007-10-25 16:46:24 UTC
gfortran links the following without error, whereas Compaq Fortran, Lahey Fortran, and g95 tell me that setbd is an unresolved external.

MODULE ksbin1_aux_mod
 CONTAINS
  SUBROUTINE nxtstg() 
    INTEGER :: i
    INTEGER :: setbd 
    i = setbd()
  END SUBROUTINE nxtstg
  FUNCTION binden() 
    INTEGER :: binden
    INTEGER :: setbd 
    binden = 0
  ENTRY setbd() 
    setbd = 0
  END FUNCTION binden
END MODULE ksbin1_aux_mod
PROGRAM test
END PROGRAM test
Comment 1 Joost VandeVondele 2007-10-25 17:33:09 UTC
this is a slightly modified testcase, which g95, NAG f95, IBM xlf90, ifort, pgf90 all compile & link while it fails to compile with gfortran. The error message by gfortran (Global name 'setbd' at (1) is already being used as a FUNCTION at (2)) suggests gfortran has a problem.

Interestingly, it returns 1 with g95, NAG f95, IBM xlf90, pgf90 and 0 with ifort.

MODULE ksbin1_aux_mod
 CONTAINS
  SUBROUTINE nxtstg()
    INTEGER :: i
    INTEGER :: setbd
    i = setbd()
    write(6,*) i
  END SUBROUTINE nxtstg
  FUNCTION binden()
    INTEGER :: binden
    INTEGER :: setbd
    binden = 0
  ENTRY setbd()
    setbd = 0
  END FUNCTION binden
END MODULE ksbin1_aux_mod
PROGRAM test
  USE ksbin1_aux_mod
  CALL nxtstg()
END PROGRAM test
INTEGER FUNCTION setbd()
  setbd=1
END FUNCTION setbd

A simpler testcase is:
MODULE M1
CONTAINS
 SUBROUTINE S2()
    ENTRY E2()
    write(6,*) 'C'
 END SUBROUTINE S2
END MODULE M1

SUBROUTINE S2()
    ENTRY E2()
    write(6,*) 'E'
END SUBROUTINE S2
Comment 2 Joost VandeVondele 2007-10-25 17:41:43 UTC
this works with gcc_4_0_branch, which makes this a regression.

MODULE M1
CONTAINS
 SUBROUTINE S2()
    ENTRY E2()
    write(6,*) 'C'
 END SUBROUTINE S2
END MODULE M1

SUBROUTINE S2()
    ENTRY E2()
    write(6,*) 'E'
END SUBROUTINE S2

USE M1
CALL E2()
END
Comment 3 Paul Thomas 2007-10-26 09:10:02 UTC
(In reply to comment #2)
> this works with gcc_4_0_branch, which makes this a regression.

Michael and Joost,

Are you sure that anything is wrong with gfortran, here?  If there is, I would agree that this is a regression.  When Michael first posted PRs on ENTRY statements in modules, I was a bit startled because ENTRY statements are a bit contrary to the spirit of modules.  That said, there is nothing wrong with it and..... according to the standard:

NOTE 11.3
Although statement function definitions, ENTRY statements, and FORMAT statements shall not appear in the specification part of a module, they may appear in the specification part of a module subprogram in the module.
A module is host to any module subprograms (12.1.2.2) it contains, and the entities in the module are therefore accessible in the module subprograms through host association.

Therefore, there is nothing wrong with having a module procedure with an entry and this note says that gfortran is right on first testscase, since setbd is made available by host association.

From 12.5.2.5, we have:

Because an ENTRY statement defines an additional function or an additional subroutine, it is referenced in the same manner as any other function or subroutine (12.4).

I take it to mean that the ENTRY in the examples given is also made available by use association.

Given these two bits of guidance from the standard, I believe that gfortran's behaviour is consistent and correct, until the additional function setbd is introduced. There, the complaint Global name 'setbd' at (1) is already being used as a FUNCTION at (2), which does not happen if the new function is called 'binden' says that there is indeed something wrong - the module entry is being promoted to a global symbol, which is not correct.

The examples of #1 are indeed bugs but not really a regression - entry in modules did not work at all!

Cheers

Paul

Comment 4 Paul Thomas 2007-10-26 09:36:40 UTC
This gives the correct behaviour:

Index: gcc/fortran/decl.c
===================================================================
*** gcc/fortran/decl.c  (révision 129434)
--- gcc/fortran/decl.c  (copie de travail)
*************** gfc_match_entry (void)
*** 4376,4382 ****
    if (state == COMP_SUBROUTINE)
      {
        /* An entry in a subroutine.  */
!       if (!add_global_entry (name, 1))
        return MATCH_ERROR;

        m = gfc_match_formal_arglist (entry, 0, 1);
--- 4376,4382 ----
    if (state == COMP_SUBROUTINE)
      {
        /* An entry in a subroutine.  */
!       if (!gfc_current_ns->parent && !add_global_entry (name, 1))
        return MATCH_ERROR;

        m = gfc_match_formal_arglist (entry, 0, 1);
*************** gfc_match_entry (void)
*** 4398,4404 ****
            ENTRY f() RESULT (r)
         can't be written as
            ENTRY f RESULT (r).  */
!       if (!add_global_entry (name, 0))
        return MATCH_ERROR;

        old_loc = gfc_current_locus;
--- 4398,4404 ----
            ENTRY f() RESULT (r)
         can't be written as
            ENTRY f RESULT (r).  */
!       if (!gfc_current_ns->parent && !add_global_entry (name, 0))
        return MATCH_ERROR;

        old_loc = gfc_current_locus;

such that 

MODULE ksbin1_aux_mod
 CONTAINS
  SUBROUTINE nxtstg()
    INTEGER :: i
    INTEGER :: setbd
    i = setbd()  ! available by host association.
    write(6,*) i
  END SUBROUTINE nxtstg
  FUNCTION binden()
    INTEGER :: binden
    INTEGER :: setbd
    binden = 0
  ENTRY setbd()
    setbd = 99
  END FUNCTION binden
END MODULE ksbin1_aux_mod

PROGRAM test
  USE ksbin1_aux_mod, only : nxtstg
  integer setbd ! setbd is external, since not use assoc.
  CALL nxtstg()
  print *, setbd ()
  call foo
contains
  subroutine foo
    USE ksbin1_aux_mod ! module setbd is available
    print *, setbd ()
  end subroutine
END PROGRAM test

INTEGER FUNCTION setbd()
  setbd=42
END FUNCTION setbd

gives

          99
          42
          99

Paul
Comment 5 Paul Thomas 2007-10-26 09:45:33 UTC
As a final remark: Digital F90 5.0 gives the result of gfortran in #4, so now I am convinced that I am right!

The Lahey source checker shows that setbd is not host associated in the module but is use associated in foo.  I'll bet that it gives:

          42
          42
          99

Paul


Paul

Comment 6 Joost VandeVondele 2007-10-26 10:42:20 UTC
(In reply to comment #5)
> As a final remark: Digital F90 5.0 gives the result of gfortran in #4, so now I
> am convinced that I am right!

I was actually not so sure as you seem to be. I agree it is intuitive to consider it available through host association. I'm only surprised that NAG, IBM, g95, Lahey, pgf90 consistently say it is not (i.e. they all print 42 42 99).

My judgement of 'regression' seems to have been a pilot error.
Comment 7 Paul Thomas 2007-10-26 13:38:05 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > As a final remark: Digital F90 5.0 gives the result of gfortran in #4, so now I
> > am convinced that I am right!
> I was actually not so sure as you seem to be. I agree it is intuitive to
> consider it available through host association. I'm only surprised that NAG,
> IBM, g95, Lahey, pgf90 consistently say it is not (i.e. they all print 42 42
> 99).

How about I take it to comp.lang.fortran?

I find nothing in the standard that says that entries should not be host associated and plenty to say that they should.  Why would entrys be availeble by use association and not by host association within the module?

Anyway, thanks for giving it your attention.

Cheers

Paul

Comment 8 Joost VandeVondele 2007-10-26 14:54:55 UTC
(In reply to comment #7)

> How about I take it to comp.lang.fortran?

yes, and Ron has given the golden clue (how easy to overlook these things). Indeed, the integer declaration of setbd in nxtstg implies that the external one has to be called as the host-associated one is inaccessible (14.6.1.3).
Comment 9 Tobias Burnus 2007-10-26 15:51:37 UTC
> > How about I take it to comp.lang.fortran?

http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/3076af3caa74347d/
Comment 10 Paul Thomas 2007-10-27 07:07:38 UTC
The logic is all wrong in parse.c(gfc_fixup_sibling_symbols).  I can fix this bug but I need to regtest and to check for other such cases in the standard.

Paul
Comment 11 Tobias Burnus 2007-10-27 13:31:28 UTC
To recap (correct me, if I'm wrong):

The program in comment 0 (original bug description) is valid Fortran, but the "setbd" is an external function which needs to be provided at link time. It is not the module function as "integer :: setbd" causes "setbd" to be an external function with an implicit interface. -> wrong-code bug as gfortran uses the module function. (see also program in comment 4.)

The first program of comment 1: I think this is valid Fortran code; what puzzles me is that gfortran rejects it with "Global name 'setbd' is already being used as a FUNCTION". I think these are complete different name spaces with the function names __ksbin1_aux_mod_MOD_setbd and setbd_: One being part of a module and the other not. The same for the second program of comment 1. -> rejects-valid.
Comment 12 Paul Thomas 2007-10-27 15:47:42 UTC
Subject: Re:  Incorrect host association in module

burnus at gcc dot gnu dot org wrote:
> ------- Comment #11 from burnus at gcc dot gnu dot org  2007-10-27 13:31 -------
> To recap (correct me, if I'm wrong):
>
> The program in comment 0 (original bug description) is valid Fortran, but the
> "setbd" is an external function which needs to be provided at link time. It is
> not the module function as "integer :: setbd" causes "setbd" to be an external
> function with an implicit interface. -> wrong-code bug as gfortran uses the
> module function. (see also program in comment 4.)
>   
Correct
> The first program of comment 1: I think this is valid Fortran code; what
> puzzles me is that gfortran rejects it with "Global name 'setbd' is already
> being used as a FUNCTION". I think these are complete different name spaces
> with the function names __ksbin1_aux_mod_MOD_setbd and setbd_: One being part
> of a module and the other not. The same for the second program of comment 1. ->
> rejects-valid.
>   
decl.c uses add_global_entry a bit too profusely.  It needs to be 
checked that the entry has global scope; ie. that gfc_current_ns->parent 
== NULL.

I have a patch that properly implements 14.6.1.3, which is regtesting as 
I write.

Cheers

paul

Comment 13 patchapp@dberlin.org 2007-10-30 03:47:45 UTC
Subject: Bug number PR33897

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-10/msg01694.html
Comment 14 patchapp@dberlin.org 2007-10-30 22:15:19 UTC
Subject: Bug number PR33897

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-10/msg01694.html
Comment 15 Tobias Burnus 2007-10-31 09:59:29 UTC
Subject: Bug 33897

Author: burnus
Date: Wed Oct 31 09:59:16 2007
New Revision: 129795

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129795
Log:
2007-10-31  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/33897
        * decl.c (gfc_match_entry): Do not make ENTRY name
        global for contained procedures.
        * parse.c (gfc_fixup_sibling_symbols): Fix code for
        determining whether a procedure is external.

2007-10-31  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/33897
        * gfortran.dg/contained_3.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/contained_3.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/decl.c
    trunk/gcc/fortran/parse.c
    trunk/gcc/testsuite/ChangeLog

Comment 16 Tobias Burnus 2007-10-31 09:59:42 UTC
FIXED on the trunk (= 4.3.0).