aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/interface.c
diff options
context:
space:
mode:
authorJerry DeLisle <jvdelisle@gcc.gnu.org>2007-10-31 14:26:57 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2007-10-31 14:26:57 +0000
commit26033479fb7d724061af07716f0077934032bbf9 (patch)
tree225d18b5b7c428001a8dd82bb1f810f3a517d524 /gcc/fortran/interface.c
parent2c26cbfd237121530e5f3b74d48de1688e3b31e6 (diff)
downloadgcc-26033479fb7d724061af07716f0077934032bbf9.zip
gcc-26033479fb7d724061af07716f0077934032bbf9.tar.gz
gcc-26033479fb7d724061af07716f0077934032bbf9.tar.bz2
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
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r--gcc/fortran/interface.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 741bba5..39f4e92 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -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)