Created attachment 29875 [details] Test case that shows the bug In short, a genericly named procedure fails to return a procedure pointer : ptr => specific_name_get_proc_ptr() ! OK ptr => generic_name_get_proc_ptr() ! KO 1 Error: Interface mismatch in procedure pointer assignment at (1): Type/rank mismatch in return value of 'generic_name_get_proc_ptr' Attached is a test case that show the problem with gfortran 4.7, 4.8 and trunk. See http://gcc.gnu.org/ml/fortran/2013-04/msg00151.html for the complete story.
Here is a draft patch which fixes the behavior for the test case: Index: gcc/fortran/expr.c =================================================================== --- gcc/fortran/expr.c (revision 197943) +++ gcc/fortran/expr.c (working copy) @@ -3540,7 +3540,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex } else if (rvalue->expr_type == EXPR_FUNCTION) { - s2 = rvalue->symtree->n.sym->result; + if (rvalue->symtree->n.sym->attr.generic) + s2 = rvalue->value.function.esym->result; + else + s2 = rvalue->symtree->n.sym->result; + name = s2->name; } else Regtesting now ...
For the record, gfortran 4.4.6 compiles the test, but not 4.5.3, 4.6.4, 4.7.3, 4.8.0, and trunk.
(In reply to comment #2) > For the record, gfortran 4.4.6 compiles the test, but not 4.5.3, 4.6.4, 4.7.3, > 4.8.0, and trunk. Oh, so it's even a regression. The 4.5 and 4.6 branches have been closed by now, I think, but we should probably backport to 4.7 and 4.8.
(In reply to comment #1) > Regtesting now ... Completed successfully. Will commit to trunk as obvious ...
(In reply to comment #1) > Index: gcc/fortran/expr.c > =================================================================== > --- gcc/fortran/expr.c (revision 197943) > +++ gcc/fortran/expr.c (working copy) > @@ -3540,7 +3540,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex > } > else if (rvalue->expr_type == EXPR_FUNCTION) > { > - s2 = rvalue->symtree->n.sym->result; > + if (rvalue->symtree->n.sym->attr.generic) > + s2 = rvalue->value.function.esym->result; > + else > + s2 = rvalue->symtree->n.sym->result; I think you should directly use if (rvalue->value.function.esym) s2 = rvalue->value.function.esym->result; I was additionally wondering whether one should also take care of isym besides esym, but probably no intrinsic returns a pointer.
(In reply to comment #5) > (In reply to comment #1) > > Index: gcc/fortran/expr.c > > =================================================================== > > --- gcc/fortran/expr.c (revision 197943) > > +++ gcc/fortran/expr.c (working copy) > > @@ -3540,7 +3540,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex > > } > > else if (rvalue->expr_type == EXPR_FUNCTION) > > { > > - s2 = rvalue->symtree->n.sym->result; > > + if (rvalue->symtree->n.sym->attr.generic) > > + s2 = rvalue->value.function.esym->result; > > + else > > + s2 = rvalue->symtree->n.sym->result; > > I think you should directly use > > if (rvalue->value.function.esym) > s2 = rvalue->value.function.esym->result; yes, I also thought about this variant. Might indeed be the better choice. > I was additionally wondering whether one should also take care of isym besides > esym, but probably no intrinsic returns a pointer. I could not find any intrinsic function which returns a pointer, and even less so a procedure pointer (which is what this patch is dealing with).
(In reply to comment #6) > > I think you should directly use > > > > if (rvalue->value.function.esym) > > s2 = rvalue->value.function.esym->result; > > yes, I also thought about this variant. Might indeed be the better choice. Ok, I have verified that this also regtests cleanly and fixes the test case (as expected). Will commit the following patch later today (unless further suggestions come up): Index: gcc/fortran/expr.c =================================================================== --- gcc/fortran/expr.c (revision 197988) +++ gcc/fortran/expr.c (working copy) @@ -3540,7 +3540,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex } else if (rvalue->expr_type == EXPR_FUNCTION) { - s2 = rvalue->symtree->n.sym->result; + if (rvalue->value.function.esym) + s2 = rvalue->value.function.esym->result; + else + s2 = rvalue->symtree->n.sym->result; + name = s2->name; } else
(In reply to comment #7) > Ok, I have verified that this also regtests cleanly and fixes the test case (as > expected). Will commit the following patch later today (unless further > suggestions come up): Looks good to me (with a test case ;-). After committal, please copy the output from your commit message at http://gcc.gnu.org/ml/gcc-cvs/current to the PR. Thanks for the patch!
Fixed on trunk with: Author: janus Date: Tue Apr 16 19:07:34 2013 New Revision: 198008 URL: http://gcc.gnu.org/viewcvs?rev=198008&root=gcc&view=rev Log: 2013-04-16 Janus Weil <janus@gcc.gnu.org> PR fortran/56968 * expr.c (gfc_check_pointer_assign): Handle generic functions returning procedure pointers. 2013-04-16 Janus Weil <janus@gcc.gnu.org> PR fortran/56968 * gfortran.dg/proc_ptr_41.f90: New. Added: trunk/gcc/testsuite/gfortran.dg/proc_ptr_41.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/expr.c trunk/gcc/testsuite/ChangeLog Will backport to 4.8 and 4.7 in a few days if no problems show up.
Fixed on the 4.8 branch with: Author: janus Date: Fri Apr 26 19:20:55 2013 New Revision: 198345 URL: http://gcc.gnu.org/viewcvs?rev=198345&root=gcc&view=rev Log: 2013-04-26 Janus Weil <janus@gcc.gnu.org> Backports from trunk: PR fortran/56814 * interface.c (check_result_characteristics): Get result from interface if present. PR fortran/56968 * expr.c (gfc_check_pointer_assign): Handle generic functions returning procedure pointers. PR fortran/53685 PR fortran/57022 * check.c (gfc_calculate_transfer_sizes): Fix for array-valued SOURCE expressions. * target-memory.h (gfc_element_size): New prototype. * target-memory.c (size_array): Remove. (gfc_element_size): New function. (gfc_target_expr_size): Modified to always return the full size of the expression. 2013-04-26 Janus Weil <janus@gcc.gnu.org> Backports from trunk: PR fortran/56968 * gfortran.dg/proc_ptr_41.f90: New. PR fortran/56814 * gfortran.dg/proc_ptr_42.f90: New. PR fortran/53685 PR fortran/57022 * gfortran.dg/transfer_check_4.f90: New. Added: branches/gcc-4_8-branch/gcc/testsuite/gfortran.dg/proc_ptr_41.f90 branches/gcc-4_8-branch/gcc/testsuite/gfortran.dg/proc_ptr_42.f90 branches/gcc-4_8-branch/gcc/testsuite/gfortran.dg/transfer_check_4.f90 Modified: branches/gcc-4_8-branch/gcc/fortran/ChangeLog branches/gcc-4_8-branch/gcc/fortran/check.c branches/gcc-4_8-branch/gcc/fortran/expr.c branches/gcc-4_8-branch/gcc/fortran/interface.c branches/gcc-4_8-branch/gcc/fortran/target-memory.c branches/gcc-4_8-branch/gcc/fortran/target-memory.h branches/gcc-4_8-branch/gcc/testsuite/ChangeLog
Fixed on the 4.7 branch with: Author: janus Date: Fri Apr 26 22:26:02 2013 New Revision: 198348 URL: http://gcc.gnu.org/viewcvs?rev=198348&root=gcc&view=rev Log: 2013-04-26 Janus Weil <janus@gcc.gnu.org> Backports from trunk: PR fortran/56968 * expr.c (gfc_check_pointer_assign): Handle generic functions returning procedure pointers. PR fortran/53685 PR fortran/57022 * check.c (gfc_calculate_transfer_sizes): Fix for array-valued SOURCE expressions. * target-memory.h (gfc_element_size): New prototype. * target-memory.c (size_array): Remove. (gfc_element_size): New function. (gfc_target_expr_size): Modified to always return the full size of the expression. 2013-04-26 Janus Weil <janus@gcc.gnu.org> Backports from trunk: PR fortran/56968 * gfortran.dg/proc_ptr_41.f90: New. PR fortran/53685 PR fortran/57022 * gfortran.dg/transfer_check_4.f90: New. Added: branches/gcc-4_7-branch/gcc/testsuite/gfortran.dg/proc_ptr_41.f90 branches/gcc-4_7-branch/gcc/testsuite/gfortran.dg/transfer_check_4.f90 Modified: branches/gcc-4_7-branch/gcc/fortran/ChangeLog branches/gcc-4_7-branch/gcc/fortran/check.c branches/gcc-4_7-branch/gcc/fortran/expr.c branches/gcc-4_7-branch/gcc/fortran/target-memory.c branches/gcc-4_7-branch/gcc/fortran/target-memory.h branches/gcc-4_7-branch/gcc/testsuite/ChangeLog Closing. Thanks for the report!