The F95 standard says (12.6): "A pure procedure is [...] or (4) A statement function that references only pure functions." But gfortran doesn't like that: $ cat a5.f90 INTEGER :: st1,i,a(4) st1(i)=i*i*i FORALL(i=1:4) a(i)=st1(i) print *, a print *, u(2) contains pure integer function u(x) integer,intent(in) :: x st2(i) = i*i u = st2(x) end function END $ gfortran a5.f90 In file a5.f90:12 u = st2(x) 1 Error: Function reference to 'st2' at (1) is to a non-PURE procedure within a PURE procedure In file a5.f90:3 FORALL(i=1:4) a(i)=st1(i) 1 Error: reference to non-PURE function 'st1' at (1) inside a FORALL block
Created attachment 12516 [details] Tentative patch This patch doesn't work :) It's working fine except that the following code: implicit none INTEGER :: st1,i,a(4) st1(i)=i*i*g(i) !FORALL(i=1:4) a(i)=st1(i) print *, a print *, u(2) contains pure integer function u(x) integer :: st2, i integer,intent(in) :: x st2(i) = i*i u = st2(x) end function pure integer function f(x) integer,intent(in) :: x f = x end function integer function g(x) integer,intent(in) :: x g = x end function end gives the erroneous error message: In file pr29389.f90:3 st1(i)=i*i*g(i) 1 Error: Function reference to 'g' at (1) is to a non-PURE procedure within a PURE procedure When the statement function is resolved, gfc_current_ns points to u. I don't understand why.
This is fixed by: resolve.c:1429 static int pure_function (gfc_expr * e, const char **name) { int pure; /* This is the fix. */ if (e->expr_type == EXPR_FUNCTION && e->symtree->n.sym->attr.proc == PROC_ST_FUNCTION) return 1; if (e->value.function.esym) The testcase should set i = 0 and test its value at the end of the main program, in order to demonstrate that there are no side-effects. Regtests OK on amd64/Cygwin_NT Paul
Subject: Bug 29389 Author: pault Date: Mon Jan 15 08:16:17 2007 New Revision: 120790 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=120790 Log: 2007-01-15 Paul Thomas <pault@gcc.gnu.org> PR fortran/28172 * trans-stmt.c (gfc_trans_call): If it does not have one, get a backend_decl for an alternate return. PR fortran/29389 * resolve.c (pure_function): Statement functions are pure. Note that this will have to recurse to comply fully with F95. PR fortran/29712 * resolve.c (resolve_function): Only a reference to the final dimension of an assumed size array is an error in an inquiry function. PR fortran/30283 * resolve.c (resolve_function): Make sure that the function expression has a type. 2007-01-15 Paul Thomas <pault@gcc.gnu.org> PR fortran/28172 * gfortran.dg/altreturn_4.f90: New test. PR fortran/29389 * gfortran.dg/stfunc_4.f90: New test. PR fortran/29712 * gfortran.dg/bound_2.f90: Reinstate commented out line. * gfortran.dg/initialization_1.f90: Change warning. PR fortran/30283 * gfortran.dg/specification_type_resolution_2.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/altreturn_4.f90 trunk/gcc/testsuite/gfortran.dg/specification_type_resolution_2.f90 trunk/gcc/testsuite/gfortran.dg/stfunc_4.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/bound_2.f90 trunk/gcc/testsuite/gfortran.dg/initialization_1.f90
> Author: pault > Date: Mon Jan 15 08:16:17 2007 > New Revision: 120790 As pointed out by FX on the list, this patch does not quite do it yet: The F95 standard says (12.6): "A pure procedure is [...] or (4) A statement function that references only pure functions." Not all statement functions are pure. Are you sure that check ("references only pure functions") is performed by your patch? I'll do this asap. Paul
Subject: Bug 29389 Author: pault Date: Tue Jan 23 05:53:14 2007 New Revision: 121077 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=121077 Log: 2007-01-23 Paul Thomas <pault@gcc.gnu.org> Backports from trunk PR fortran/28172 * trans-stmt.c (gfc_trans_call): If it does not have one, get a backend_decl for an alternate return. PR fortran/29389 * resolve.c (pure_function): Statement functions are pure. Note that this will have to recurse to comply fully with F95. PR fortran/29712 * resolve.c (resolve_function): Only a reference to the final dimension of an assumed size array is an error in an inquiry function. PR fortran/30283 * resolve.c (resolve_function): Make sure that the function expression has a type. 2007-01-23 Paul Thomas <pault@gcc.gnu.org> PR fortran/28172 * gfortran.dg/altreturn_4.f90: New test. PR fortran/29389 * gfortran.dg/stfunc_4.f90: New test. PR fortran/29712 * gfortran.dg/bound_2.f90: Reinstate commented out line. * gfortran.dg/initialization_1.f90: Change warning. PR fortran/30283 * gfortran.dg/specification_type_resolution_2.f90: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/altreturn_4.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/specification_type_resolution_2.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/stfunc_4.f90 Modified: branches/gcc-4_2-branch/gcc/fortran/ChangeLog branches/gcc-4_2-branch/gcc/fortran/resolve.c branches/gcc-4_2-branch/gcc/fortran/trans-stmt.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/bound_2.f90 branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/initialization_1.f90
Partially fixed - see list. Paul
list link: http://gcc.gnu.org/ml/fortran/2007-01/msg00361.html this suggests that it is now an accepts-invalid bug with an easy fix (Bug reporter / assignee should change keyword)
Subject: Bug 29389 Author: pault Date: Tue Nov 27 20:47:55 2007 New Revision: 130472 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130472 Log: 2007-11-27 Paul Thomas <pault@gcc.gnu.org> PR fortran/29389 *resolve.c (resolve_ordinary_assign): Use find_sym_in_expr to test if a temporary should be written for a vector subscript on the lhs. PR fortran/33850 * restore.c (pure_stmt_function): Add prototype and new function. Calls impure_stmt_fcn. (pure_function): Call it. (impure_stmt_fcn): New function. * expr.c (gfc_traverse_expr): Call *func for all expression types, not just variables. Add traversal of character lengths, iterators and component character lengths and arrayspecs. (expr_set_symbols_referenced): Return false if not a variable. * trans-stmt.c (forall_replace, forall_restore): Ditto. * resolve.c (forall_index): Ditto. (sym_in_expr): New function. (find_sym_in_expr): Rewrite to traverse expression calling sym_in_expr. *trans-decl.c (expr_decls): New function. (generate_expr_decls): Rewrite to traverse expression calling expr_decls. *match.c (check_stmt_fcn): New function. (recursive_stmt_fcn): Rewrite to traverse expression calling check_stmt_fcn. 2007-11-27 Paul Thomas <pault@gcc.gnu.org> PR fortran/29389 * gfortran.dg/stfunc_6.f90: New test. PR fortran/33850 * gfortran.dg/assign_10.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/assign_10.f90 trunk/gcc/testsuite/gfortran.dg/stfunc_6.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/expr.c trunk/gcc/fortran/match.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/testsuite/ChangeLog
Fixed on trunk Paul
Note that before the patch for pr35837, the code in comment #1 was wrongly rejected. This is now fixed by this patch. Also if the FORALL statement is this code is uncommented, it is now accepted while it is invalid, see pr37398.