This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Procedure Pointers: a first patch


Janus Weil wrote:
I have some more things, which fail. Maybe it makes sense to check-in a
half-finished patch and continue with the fixing of the smaller items later.
For the moment I'm working on procptr formal arguments and return
values (see proc_ptr_4.f90). In particular I have trouble seeing why I
get a segfault there. Any help appreciated.
You probably made the same mistake as I did: The procedure pointer is passed by value and not by reference.

See C test program below.

I tried to fix it in Fortran, but I have not yet found the proper place. My incomplete patch is:
------------------------------------
Index: trans-expr.c
===================================================================
--- trans-expr.c (Revision 135849)
+++ trans-expr.c (Arbeitskopie)
@@ -2470,8 +2490,10 @@ gfc_conv_function_call (gfc_se * se, gfc
else
{
gfc_conv_expr_reference (&parmse, e);
- if (fsym && fsym->attr.pointer
- && fsym->attr.flavor != FL_PROCEDURE
+ if (fsym
+ && ((fsym->attr.pointer
+ && fsym->attr.flavor != FL_PROCEDURE)
+ || fsym->attr.proc_pointer)
&& e->expr_type != EXPR_NULL)
{
/* Scalar pointer dummy args require an extra level of
124,1 Ende
Index: trans-decl.c
===================================================================
--- trans-decl.c (Revision 135849)
+++ trans-decl.c (Arbeitskopie)
@@ -1540,6 +1574,9 @@ create_function_arglist (gfc_symbol * sy
type = gfc_sym_type (f->sym);
}


+      if (f->sym->attr.proc_pointer)
+       type = build_pointer_type (type);
+
      /* Build a the argument declaration.  */
      parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type);

------------------------------------

In principle this looks quite OK, except for one line:

s_out (real(kind=4) (*<T2e7>) (void) * p)
 p = (real(kind=4) (*<T2e7>) (void) *) _gfortran_specific__abs_r4;
 static void s_out (real(kind=4) (*<T2e7>) (void)); // <<<<<<<<<<<<<<
 s_out (&ptr2);

Except the third line should have another *.

I won't fix this today.

Tobias


#include <stdio.h>


double ret(double x)
{
 return -x;
}

typedef double(*fp)(double);

void assign3(fp *x)
{
 *x = &ret;
}

void assign(double (*(*x)) (double))
{
 x = (fp *) ret;
}


double (*assign2(void))(double) { return &ret; }

int main() {
 double (*p) (double);
//  p = &ret; // works
//  p = assign2(); // works
 assign3(&p); // works
 printf("%e\n", p(3.3));
 return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]