aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/interface.c
diff options
context:
space:
mode:
authorTobias Burnus <burnus@net-b.de>2011-09-14 08:26:07 +0200
committerTobias Burnus <burnus@gcc.gnu.org>2011-09-14 08:26:07 +0200
commitea8ad3e527332487c4e395a95d9588873a58a99b (patch)
treeea05e76ae4fb515f8b3075f732a237a358ae0f9f /gcc/fortran/interface.c
parent95a45b570dac0fa415570b77a8ac874caba8481f (diff)
downloadgcc-ea8ad3e527332487c4e395a95d9588873a58a99b.zip
gcc-ea8ad3e527332487c4e395a95d9588873a58a99b.tar.gz
gcc-ea8ad3e527332487c4e395a95d9588873a58a99b.tar.bz2
re PR fortran/34547 (NULL(): Fortran 2003 changes, accepts invalid, ICE on invalid)
2011-09-14 Tobias Burnus <burnus@net-b.de> PR fortran/34547 PR fortran/50375 * check.c (gfc_check_null): Allow allocatables as MOLD to NULL. * resolve.c (resolve_transfer): Reject NULL without MOLD. * interface.c (gfc_procedure_use): Reject NULL without MOLD if no explicit interface is known. (gfc_search_interface): Reject NULL without MOLD if it would lead to ambiguity. 2011-09-14 Tobias Burnus <burnus@net-b.de> PR fortran/34547 PR fortran/50375 * gfortran.dg/null_5.f90: New. * gfortran.dg/null_6.f90: New. From-SVN: r178841
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r--gcc/fortran/interface.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index a9b3d70..7962403 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -2857,6 +2857,13 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
"procedure '%s'", &a->expr->where, sym->name);
break;
}
+
+ if (a->expr && a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN)
+ {
+ gfc_error ("MOLD argument to NULL required at %L", &a->expr->where);
+ return;
+ }
}
return;
@@ -2949,6 +2956,20 @@ gfc_search_interface (gfc_interface *intr, int sub_flag,
gfc_actual_arglist **ap)
{
gfc_symbol *elem_sym = NULL;
+ gfc_symbol *null_sym = NULL;
+ locus null_expr_loc;
+ gfc_actual_arglist *a;
+ bool has_null_arg = false;
+
+ for (a = *ap; a; a = a->next)
+ if (a->expr && a->expr->expr_type == EXPR_NULL
+ && a->expr->ts.type == BT_UNKNOWN)
+ {
+ has_null_arg = true;
+ null_expr_loc = a->expr->where;
+ break;
+ }
+
for (; intr; intr = intr->next)
{
if (sub_flag && intr->sym->attr.function)
@@ -2958,6 +2979,19 @@ gfc_search_interface (gfc_interface *intr, int sub_flag,
if (gfc_arglist_matches_symbol (ap, intr->sym))
{
+ if (has_null_arg && null_sym)
+ {
+ gfc_error ("MOLD= required in NULL() argument at %L: Ambiguity "
+ "between specific functions %s and %s",
+ &null_expr_loc, null_sym->name, intr->sym->name);
+ return NULL;
+ }
+ else if (has_null_arg)
+ {
+ null_sym = intr->sym;
+ continue;
+ }
+
/* Satisfy 12.4.4.1 such that an elemental match has lower
weight than a non-elemental match. */
if (intr->sym->attr.elemental)
@@ -2969,6 +3003,9 @@ gfc_search_interface (gfc_interface *intr, int sub_flag,
}
}
+ if (null_sym)
+ return null_sym;
+
return elem_sym ? elem_sym : NULL;
}