This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
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;
}