}
+/* Procedure pointer as function result: Replace the function symbol by the
+ auto-generated hidden result variable named "ppr@". */
+
+static gfc_try
+replace_hidden_procptr_result (gfc_symbol **sym, gfc_symtree **st)
+{
+ /* Check for procedure pointer result variable. */
+ if ((*sym)->attr.function && !(*sym)->attr.external
+ && (*sym)->result && (*sym)->result != *sym
+ && (*sym)->result->attr.proc_pointer
+ && (*sym) == gfc_current_ns->proc_name
+ && (*sym) == (*sym)->result->ns->proc_name
+ && strcmp ("ppr@", (*sym)->result->name) == 0)
+ {
+ /* Automatic replacement with "hidden" result variable. */
+ (*sym)->result->attr.referenced = (*sym)->attr.referenced;
+ *sym = (*sym)->result;
+ *st = gfc_find_symtree ((*sym)->ns->sym_root, (*sym)->name);
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+
/* Matches a variable name followed by anything that might follow it--
array reference, argument list of a function, etc. */
e = NULL;
where = gfc_current_locus;
+ replace_hidden_procptr_result (&sym, &symtree);
+
/* If this is an implicit do loop index and implicitly typed,
it should not be host associated. */
m = check_for_implicit_index (&symtree, &sym);
gfc_get_ha_sym_tree (name, &symtree); /* Can't fail */
sym = symtree->n.sym;
+ replace_hidden_procptr_result (&sym, &symtree);
+
e = gfc_get_expr ();
e->symtree = symtree;
e->expr_type = EXPR_FUNCTION;
break;
}
- if (sym->attr.proc_pointer)
+ if (sym->attr.proc_pointer
+ || replace_hidden_procptr_result (&sym, &st) == SUCCESS)
break;
/* Fall through to error */