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);
 }
