Hello,
here is a fix for PR fortran/55827 where we had a function expression
(loaded from a module) whose symtree pointer was NULL. My attempt to
have symtree properly set got me way too far, so this is fixing the
unconditional usages of symtree based on Steve's patch in the PR. As
noted in the PR, it looks bogus to have a NULL expr->symtree, but in
fact expr->value.function.esym is set, and it is what is solely looked
at, apart for the cases fixed in this patch.
The trans-expr.c part initializes `sym' earlier and uses it instead of
accessing `expr->symtree' directly.
The class.c part creates a similar construct to initialize `ts' without
accessing `expr->symtree' directly. I don't use Steve's way (returning
early for a NULL symtree), because I remembered that `expr->symtree'
could be a generic symbol, thus have invalid type for use to initialize
`ts', contrary to `expr->value.function.esym'. It's better to always
use `esym' when it is available. And then returning early on NULL
symtree is not necessary any more.
Regression tested on x86_64-unknown-linux-gnu. OK for trunk?
Do we want it on the branches as well?
Mikael
2013-01-03 Steven G. Kargl <ka...@gcc.gnu.org>
Mikael Morin <mik...@gcc.gnu.org>
* class.c (gfc_fix_class_refs): Adapt ts initialization for the case
e->symtree == NULL.
* trans-expr.c (gfc_conv_function_expr): Init sym earlier. Use it.
diff --git a/class.c b/class.c
index 8a8a54a..8b00a2c 100644
--- a/class.c
+++ b/class.c
@@ -166,7 +166,23 @@ gfc_fix_class_refs (gfc_expr *e)
&& e->value.function.isym != NULL))
return;
- ts = &e->symtree->n.sym->ts;
+ if (e->expr_type == EXPR_VARIABLE)
+ ts = &e->symtree->n.sym->ts;
+ else
+ {
+ gfc_symbol *func;
+
+ gcc_assert (e->expr_type == EXPR_FUNCTION);
+ if (e->value.function.esym != NULL)
+ func = e->value.function.esym;
+ else
+ func = e->symtree->n.sym;
+
+ if (func->result != NULL)
+ ts = &func->result->ts;
+ else
+ ts = &func->ts;
+ }
for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
{
diff --git a/trans-expr.c b/trans-expr.c
index 42f6e0c..d36b466 100644
--- a/trans-expr.c
+++ b/trans-expr.c
@@ -5420,20 +5420,20 @@ gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
return;
}
+ /* expr.value.function.esym is the resolved (specific) function symbol for
+ most functions. However this isn't set for dummy procedures. */
+ sym = expr->value.function.esym;
+ if (!sym)
+ sym = expr->symtree->n.sym;
+
/* We distinguish statement functions from general functions to improve
runtime performance. */
- if (expr->symtree->n.sym->attr.proc == PROC_ST_FUNCTION)
+ if (sym->attr.proc == PROC_ST_FUNCTION)
{
gfc_conv_statement_function (se, expr);
return;
}
- /* expr.value.function.esym is the resolved (specific) function symbol for
- most functions. However this isn't set for dummy procedures. */
- sym = expr->value.function.esym;
- if (!sym)
- sym = expr->symtree->n.sym;
-
gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
NULL);
}
2013-01-03 Steven G. Kargl <ka...@gcc.gnu.org>
Mikael Morin <mik...@gcc.gnu.org>
* gfortran.dg/use_10.f90: New test.
! { dg-do compile }
!
! PR fortran/55827
! gfortran used to ICE with the call to `tostring' depending on how the
! `tostring' symbol was USE-associated.
!
! Contributed by Lorenz Hüdepohl <b...@stellardeath.org>
module stringutils
interface
pure function strlen(handle) result(len)
integer, intent(in) :: handle
integer :: len
end function
end interface
end module
module intermediate ! does not die if this module is merged with stringutils
contains
function tostring(handle) result(string)
use stringutils
integer, intent(in) :: handle
character(len=strlen(handle)) :: string
end function
end module
module usage
contains
subroutine dies_here(handle)
use stringutils ! does not die if this unnecessary line is omitted or placed after "use intermediate"
use intermediate
integer :: handle
write(*,*) tostring(handle) ! ICE
end subroutine
end module