Bug 42072 - [F03] wrong-code with C_F_PROCPOINTER
Summary: [F03] wrong-code with C_F_PROCPOINTER
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-11-16 22:48 UTC by janus
Modified: 2009-11-20 16:08 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-11-16 22:59:51


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2009-11-16 22:48:10 UTC
The following variant of proc_ptr_8.* fails at runtime:


! { dg-do run }
! { dg-additional-sources proc_ptr_8.c }

MODULE X

  USE ISO_C_BINDING
  INTERFACE
    INTEGER(KIND=C_INT) FUNCTION mytype( a ) BIND(C)
       USE ISO_C_BINDING
       INTEGER(KIND=C_INT), VALUE :: a
    END FUNCTION
    SUBROUTINE init() BIND(C,name="init")
    END SUBROUTINE
  END INTERFACE

  TYPE(C_FUNPTR), BIND(C,name="funpointer") :: funpointer

END MODULE X

USE X
PROCEDURE(mytype), POINTER :: ptype

CALL init()
call setpointer(ptype)
if (ptype(3) /= 9) call abort()

contains

  subroutine setpointer (p)
    PROCEDURE(mytype), POINTER :: p
    CALL C_F_PROCPOINTER(funpointer,p)
  end subroutine

END

! { dg-final { cleanup-modules "X" } }


/* Used by proc_ptr_8.f90.
   PR fortran/32580.  */

int (*funpointer)(int);

int f(int t)
{
  return t*3;
}

void init()
{
 funpointer=f;
}
Comment 1 janus 2009-11-16 22:51:28 UTC
Side-note on C_F_PROCPOINTER: The manual claims that ...

"Due to the currently lacking support of procedure pointers in GNU Fortran this function is not fully operable."

... which is a dirty lie.
Comment 2 janus 2009-11-16 22:55:50 UTC
Proposed fix:

Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c    (revision 154189)
+++ gcc/fortran/trans-expr.c    (working copy)
@@ -2645,6 +2645,12 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol *
            tmp = gfc_get_ppc_type (arg->next->expr->ref->u.c.component);
          else
            tmp = TREE_TYPE (arg->next->expr->symtree->n.sym->backend_decl);
+
+         if (arg->next->expr->symtree->n.sym->attr.proc_pointer
+             && arg->next->expr->symtree->n.sym->attr.dummy)
+           fptrse.expr = build_fold_indirect_ref_loc (input_location,
+                                                      fptrse.expr);
+
          se->expr = fold_build2 (MODIFY_EXPR, tmp, fptrse.expr,
                                  fold_convert (tmp, cptrse.expr));

Comment 3 Andrew Pinski 2009-11-16 22:59:50 UTC
call setpointer(ptype)
is being converted into:
  setpointer.1481 ();

So inside MAIN__ we have:
  static void setpointer (integer(kind=4) (*<T3af>) (integer(kind=4)));
  setpointer (&ptype);


That is wrong, unless I am missing a reference type somewhere.


Plus inside setpointer I think:
  p = (integer(kind=4) (*<T3af>) (integer(kind=4)) *) funpointer;

is incorrect, it should be:
*p = funpointer;
Comment 4 Andrew Pinski 2009-11-16 23:00:18 UTC
Wrong buttons :).
Comment 5 janus 2009-11-17 12:00:31 UTC
(In reply to comment #3)
> So inside MAIN__ we have:
>   static void setpointer (integer(kind=4) (*<T3af>) (integer(kind=4)));
>   setpointer (&ptype);
> 
> That is wrong, unless I am missing a reference type somewhere.

Yes, indeed the 'static' line is wrong. However, it does not seem to have any consequences.


> Plus inside setpointer I think:
>   p = (integer(kind=4) (*<T3af>) (integer(kind=4)) *) funpointer;
> 
> is incorrect, it should be:
> *p = funpointer;

Right, this is corrected by my patch in comment #2. With that patch, the dump shows:


setpointer (integer(kind=4) (*<T3d4>) (integer(kind=4)) * p)
{
  *p = (integer(kind=4) (*<T3d4>) (integer(kind=4))) funpointer;
}

MAIN__ ()
{
  extern void (*<T62>) (void) funpointer;
  integer(kind=4) (*<T3d4>) (integer(kind=4)) ptype;
  integer(kind=4) (*<T3d4>) (integer(kind=4)) ptype2;
  static void setpointer (integer(kind=4) (*<T3d4>) (integer(kind=4)));

Here the 'setpointer' routine is ok, but again the static declaration is wrong.
Comment 6 janus 2009-11-18 13:25:18 UTC
Subject: Bug 42072

Author: janus
Date: Wed Nov 18 13:24:54 2009
New Revision: 154292

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=154292
Log:
2009-11-18  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42072
	* trans-expr.c (gfc_conv_procedure_call): Handle procedure pointer
	dummies which are passed to C_F_PROCPOINTER.


2009-11-18  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42072
	* gfortran.dg/proc_ptr_8.f90: Extended.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_8.f90

Comment 7 janus 2009-11-20 15:51:12 UTC
The runtime problem and the obsolete comment in the manual are fixed now. So the only issue left is the wrong static declaration reported in comment #3.
Comment 8 janus 2009-11-20 16:08:43 UTC
(In reply to comment #7)
> So the only issue left is the wrong static declaration reported in comment #3.

This is now PR 42122. Closing this one.