re PR fortran/33162 (INTRINSIC functions as ACTUAL argument)
2007-10-31 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/33162 * interface.c (compare_intr_interfaces): New function to check intrinsic function arguments against formal arguments. (compare_interfaces): Fix logic in comparison of function and subroutine attributes. (compare_parameter): Use new function for intrinsic as argument. * resolve.c (resolve_actual_arglist): Allow an intrinsic without function attribute to be checked further. Set function attribute if intrinsic symbol is found, return FAILURE if not. From-SVN: r129798
This commit is contained in:
parent
2c26cbfd23
commit
26033479fb
@ -1,3 +1,14 @@
|
||||
2007-10-31 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR fortran/33162
|
||||
* interface.c (compare_intr_interfaces): New function to check intrinsic
|
||||
function arguments against formal arguments. (compare_interfaces): Fix
|
||||
logic in comparison of function and subroutine attributes.
|
||||
(compare_parameter): Use new function for intrinsic as argument.
|
||||
* resolve.c (resolve_actual_arglist): Allow an intrinsic without
|
||||
function attribute to be checked further. Set function attribute if
|
||||
intrinsic symbol is found, return FAILURE if not.
|
||||
|
||||
2007-10-31 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/33897
|
||||
|
@ -468,6 +468,7 @@ compare_type_rank (gfc_symbol *s1, gfc_symbol *s2)
|
||||
|
||||
|
||||
static int compare_interfaces (gfc_symbol *, gfc_symbol *, int);
|
||||
static int compare_intr_interfaces (gfc_symbol *, gfc_symbol *);
|
||||
|
||||
/* Given two symbols that are formal arguments, compare their types
|
||||
and rank and their formal interfaces if they are both dummy
|
||||
@ -942,7 +943,7 @@ compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag)
|
||||
gfc_formal_arglist *f1, *f2;
|
||||
|
||||
if (s1->attr.function != s2->attr.function
|
||||
&& s1->attr.subroutine != s2->attr.subroutine)
|
||||
|| s1->attr.subroutine != s2->attr.subroutine)
|
||||
return 0; /* Disagreement between function/subroutine. */
|
||||
|
||||
f1 = s1->formal;
|
||||
@ -973,6 +974,56 @@ compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
compare_intr_interfaces (gfc_symbol *s1, gfc_symbol *s2)
|
||||
{
|
||||
static gfc_formal_arglist *f, *f1;
|
||||
static gfc_intrinsic_arg *fi, *f2;
|
||||
gfc_intrinsic_sym *isym;
|
||||
|
||||
if (s1->attr.function != s2->attr.function
|
||||
|| s1->attr.subroutine != s2->attr.subroutine)
|
||||
return 0; /* Disagreement between function/subroutine. */
|
||||
|
||||
isym = gfc_find_function (s2->name);
|
||||
|
||||
/* This should already have been checked in
|
||||
resolve.c (resolve_actual_arglist). */
|
||||
gcc_assert (isym);
|
||||
|
||||
f1 = s1->formal;
|
||||
f2 = isym->formal;
|
||||
|
||||
/* Special case. */
|
||||
if (f1 == NULL && f2 == NULL)
|
||||
return 1;
|
||||
|
||||
/* First scan through the formal argument list and check the intrinsic. */
|
||||
fi = f2;
|
||||
for (f = f1; f; f = f->next)
|
||||
{
|
||||
if (fi == NULL)
|
||||
return 0;
|
||||
if ((fi->ts.type != f->sym->ts.type) || (fi->ts.kind != f->sym->ts.kind))
|
||||
return 0;
|
||||
fi = fi->next;
|
||||
}
|
||||
|
||||
/* Now scan through the intrinsic argument list and check the formal. */
|
||||
f = f1;
|
||||
for (fi = f2; fi; fi = fi->next)
|
||||
{
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
if ((fi->ts.type != f->sym->ts.type) || (fi->ts.kind != f->sym->ts.kind))
|
||||
return 0;
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Given a pointer to an interface pointer, remove duplicate
|
||||
interfaces and make sure that all symbols are either functions or
|
||||
subroutines. Returns nonzero if something goes wrong. */
|
||||
@ -1323,7 +1374,10 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
|
||||
|| actual->symtree->n.sym->attr.external)
|
||||
return 1; /* Assume match. */
|
||||
|
||||
return compare_interfaces (formal, actual->symtree->n.sym, 0);
|
||||
if (actual->symtree->n.sym->attr.intrinsic)
|
||||
return compare_intr_interfaces (formal, actual->symtree->n.sym);
|
||||
else
|
||||
return compare_interfaces (formal, actual->symtree->n.sym, 0);
|
||||
}
|
||||
|
||||
if ((actual->expr_type != EXPR_NULL || actual->ts.type != BT_UNKNOWN)
|
||||
|
@ -1071,8 +1071,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
|
||||
goto got_variable;
|
||||
|
||||
/* If all else fails, see if we have a specific intrinsic. */
|
||||
if (sym->attr.function
|
||||
&& sym->ts.type == BT_UNKNOWN && sym->attr.intrinsic)
|
||||
if (sym->ts.type == BT_UNKNOWN && sym->attr.intrinsic)
|
||||
{
|
||||
gfc_intrinsic_sym *isym;
|
||||
isym = gfc_find_function (sym->name);
|
||||
@ -1081,8 +1080,10 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
|
||||
gfc_error ("Unable to find a specific INTRINSIC procedure "
|
||||
"for the reference '%s' at %L", sym->name,
|
||||
&e->where);
|
||||
return FAILURE;
|
||||
}
|
||||
sym->ts = isym->ts;
|
||||
sym->attr.function = 1;
|
||||
}
|
||||
goto argument_list;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user