Bug 46100

Summary: [Fortran 2008] Non-variable pointer expression as actual argument to INTENT(OUT) non-pointer dummy
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal Keywords: rejects-valid
Priority: P3    
Version: 4.6.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 39627    

Description Tobias Burnus 2010-10-20 16:43:44 UTC
Reported at c.l.f by Thomas Jahns:
http://groups.google.com/group/comp.lang.fortran/browse_thread/thread
/a64e2f255466a87a

GNU Fortran (and most other compilers) reject passing a non-variable pointer expression as actual argument to an INTENT(OUT)/INTENT(INOUT) non-pointer dummy argument.

The reason for rejecting is that the pointer expression (i.e. a function returning a pointer) itself is not definable. However, I believe now that it the code is valid. Thus, only if the argument were a pointer dummy or the expression were not a pointer expression, it would be invalid.

Example:

call one (two ())
contains
  subroutine one (x)
    integer, intent(inout) :: x
  end subroutine one
  function two ()
    integer, pointer :: two
    allocate(two)
  end function two
end

Error message:

call one (two ())
          1
Error: Non-variable expression in variable definition context (actual argument to INTENT = OUT/INOUT) at (1)
Comment 1 Tobias Burnus 2010-10-20 17:21:30 UTC
Forgot to add: In the current ISO Fortran standard (Fortran 2008), one finds:

"If a nonpointer dummy argument without the VALUE attribute corresponds
to a pointer actual argument that is pointer associated with a target,
the dummy argument becomes argument associated with that target."

"The INTENT (INOUT) attribute for a nonpointer dummy argument specifies
that any actual argument that corresponds to the dummy argument shall be
definable."

"definable -- capable of definition and permitted to become defined"

Thus, it boils down to the questions whether the target (to which the
pointer is pointer associated) is definable. I think that is usually
the case, which makes the example valid.

 * * *

Note, however, that Richard Maine disagrees - he thinks that it is invalid Fortran 2003, while it might be valid Fortran 2008. I cannot see an essential difference between the F2003 and F2008 wording, but there might be.

(See thread and see interpretation request F95/0074 in http://j3-fortran.org/doc/standing/links/022.txt . Using a pointer function as LHS of an assignment is tracked by F2008's PR 40054.)
Comment 2 Tobias Burnus 2010-10-20 17:45:27 UTC
After carefully reading the interpretation request, http://www.j3-fortran.org/doc/year/08/08-172.txt, I think the reason that it is invalid in Fortran 95/2003 is that only variables are definable and as "f()" is not a variable, it is invalid.

Fortran 2008 has (cf. PR 40054):
   R602 variable  is  designator
                  or  expr
   C602 (R602) expr shall be a reference to a function that has a pointer
               result."

Which makes the program valid.
Comment 3 Tobias Burnus 2010-10-20 18:01:54 UTC
Untested patch:

diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 5711634..ef516a4 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -4316,7 +4316,18 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, const char* context)
   symbol_attribute attr;
   gfc_ref* ref;

-  if (e->expr_type != EXPR_VARIABLE)
+  if (!pointer && e->expr_type == EXPR_FUNCTION
+      && e->symtree->n.sym->result->attr.pointer)
+    {
+      if (!(gfc_option.allow_std & GFC_STD_F2008))
+       {
+         if (context)
+           gfc_error ("Fortran 2008: Pointer functions in variable definition"
+                      " context (%s) at %L", context, &e->where);
+         return FAILURE;
+       }
+    }
+  else if (e->expr_type != EXPR_VARIABLE)
     {
       if (context)
        gfc_error ("Non-variable expression in variable definition context (%s)"
Comment 4 Tobias Burnus 2010-10-21 06:15:34 UTC
Author: burnus
Date: Thu Oct 21 06:15:30 2010
New Revision: 165749

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=165749
Log:
2010-10-21  Tobias Burnus  <burnus@net-b.de>

        PR fortran/46100
        * expr.c (gfc_check_vardef_context): Treat pointer functions
        as variables.

2010-10-21  Tobias Burnus  <burnus@net-b.de>

        PR fortran/46100
        * gfortran.dg/ptr-func-1.f90: New.
        * gfortran.dg/ptr-func-2.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/ptr-func-1.f90
    trunk/gcc/testsuite/gfortran.dg/ptr-func-2.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Tobias Burnus 2010-10-21 06:16:59 UTC
FIXED on the trunk (4.6).