Bug 56968 - [4.7/4.8/4.9 Regression] [F03] Issue with a procedure defined with a generic name returning procedure pointer
Summary: [4.7/4.8/4.9 Regression] [F03] Issue with a procedure defined with a generic ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-04-15 14:07 UTC by Samuel Debionne
Modified: 2013-04-26 22:30 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.4.6
Known to fail: 4.5.3, 4.6.4, 4.7.3, 4.8.0, 4.9.0
Last reconfirmed: 2013-04-15 00:00:00


Attachments
Test case that shows the bug (240 bytes, text/plain)
2013-04-15 14:07 UTC, Samuel Debionne
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Debionne 2013-04-15 14:07:52 UTC
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.
Comment 1 janus 2013-04-15 14:44:25 UTC
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 ...
Comment 2 Dominique d'Humieres 2013-04-15 15:02:48 UTC
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.
Comment 3 janus 2013-04-15 17:15:51 UTC
(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.
Comment 4 janus 2013-04-15 17:16:50 UTC
(In reply to comment #1)
> Regtesting now ...

Completed successfully. Will commit to trunk as obvious ...
Comment 5 Tobias Burnus 2013-04-15 17:35:57 UTC
(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.
Comment 6 janus 2013-04-15 18:35:56 UTC
(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).
Comment 7 janus 2013-04-16 08:50:35 UTC
(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
Comment 8 Tobias Burnus 2013-04-16 08:54:19 UTC
(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!
Comment 9 janus 2013-04-16 19:14:33 UTC
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.
Comment 10 janus 2013-04-26 19:31:41 UTC
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
Comment 11 janus 2013-04-26 22:30:41 UTC
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!