Message ID | 50E5F8B4.6080507@sfr.fr |
---|---|
State | New |
Headers | show |
Dear Mikael and Steve, From a quick read of your correspondence in the PR, you seem to have covered all the angles between you. OK for trunk. As for the branches; yes, but.... how far back to go? I guess that 4.6 and 4.7 should be patched, if possible, since they are in current use in distributions. However, I note that class.c(gfc_fix_class_refs) is dated 2012-02-02 and was applied to 4.7.0 trunk. Is the bug present 4.6? I have neither tree loaded since updating my system and so cannot check at the moment. Thanks for the patch. Paul On 3 January 2013 22:31, Mikael Morin <mikael.morin@sfr.fr> wrote: > 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 > > > > > > >
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); }