Bug 32881 - PURE attribute escapes from contained procedure
PURE attribute escapes from contained procedure
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.3.0
: P3 normal
: 4.3.0
Assigned To: Paul Thomas
: rejects-valid
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2007-07-24 16:13 UTC by Janne Blomqvist
Modified: 2007-08-18 11:22 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-08-14 16:44:34


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Janne Blomqvist 2007-07-24 16:13:50 UTC
The following testcase is AFAICT legal:

subroutine foo ()
  integer, pointer :: p => NULL()
contains
  pure function bar (a)
    integer, intent(in) :: a
    integer :: bar
    bar = a
  end function bar
end subroutine foo

gfortran refuses to compile it, complaining

pure-escape.f90:2.23:

  integer, pointer :: p => NULL()
                      1
Error: Bad pointer object in PURE procedure at (1)


Remove the pure attribute from the contained function "bar", or the "=> NULL()" initialization of the pointer, and it compiles. Both ifort and the Lahey online checker accept the code, and I can't really see how the standard could say otherwise. 

My guess is that gfortran thinks foo is also pure, and hence initializing p means that it's saved and thus it complains.
Comment 1 Tobias Burnus 2007-07-24 17:22:47 UTC
Confirmed.

The problem is that  gfc_pure(NULL) is called and thus
  sym = gfc_current_ns->proc_name;
is used as procedure symbol, which is "bar" and not "foo".

The following patch fixes this, but I have not regtested it.
Index: expr.c
===================================================================
--- expr.c      (Revision 126873)
+++ expr.c      (Arbeitskopie)
@@ -2734,7 +2743,7 @@
       return FAILURE;
     }

-  is_pure = gfc_pure (NULL);
+  is_pure = gfc_pure (lvalue->symtree->n.sym->ns->proc_name);

   if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym))
     {
Comment 2 Tobias Burnus 2007-07-24 20:53:26 UTC
Of cause it did not regtest :-(
(fails for impure_assignment_2.f90, l.58, were "B" is a host-associated variable; thus gfc_pure(NULL) seems to be ok.)

The problem is actually that gfc_check_pointer_assign is called twice. Once gfc_current_ns->proc_name->name is correctly "foo", but the second time gfc_current_ns->proc_name->name is "bar"; in the latter case the call tree looks as follows: gfc_check_pointer_assign <- gfc_check_assign_symbol <- traverse_ns <- resolve_types. In resolve types: "gfc_current_ns = ns;"
Comment 3 Daniel Franke 2007-07-29 13:01:41 UTC
This is accepted:

$> cat pr32881.f90
program foo
  integer :: i = 42
  print *, bar()
contains
  pure integer function bar ()
    bar = i
  end function
end program
Comment 4 Paul Thomas 2007-08-14 16:44:34 UTC
This fixes the problem.  However there are some odd regressions that do not seem to have anything to do with it but which must be investigated.

Paul

Index: gcc/fortran/expr.c
===================================================================
*** gcc/fortran/expr.c  (revision 127396)
--- gcc/fortran/expr.c  (working copy)
*************** gfc_check_pointer_assign (gfc_expr *lval
*** 2739,2745 ****

    is_pure = gfc_pure (NULL);

!   if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym))
      {
        gfc_error ("Bad pointer object in PURE procedure at %L", &lvalue->where)
;
        return FAILURE;
--- 2739,2746 ----

    is_pure = gfc_pure (NULL);

!   if (is_pure && gfc_impure_variable (lvalue->symtree->n.sym)
!       && lvalue->symtree->n.sym->value != rvalue)
      {
        gfc_error ("Bad pointer object in PURE procedure at %L", &lvalue->where)
;
        return FAILURE;
Comment 5 patchapp@dberlin.org 2007-08-17 15:10:41 UTC
Subject: Bug number PR32881

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-08/msg01078.html
Comment 6 Paul Thomas 2007-08-18 10:48:10 UTC
Subject: Bug 32881

Author: pault
Date: Sat Aug 18 10:47:58 2007
New Revision: 127611

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

	PR fortran/32881
	* expr.c (gfc_check_pointer_assign): If the rhs is the
	initialization expression for the rhs, there is no error.

2007-08-18  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/32881
	* gfortran.dg/pure_initializer_1.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/pure_initializer_1.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Paul Thomas 2007-08-18 11:22:05 UTC
Fixed on trunk.

Paul