summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authormikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-14 16:45:55 +0000
committermikael <mikael@138bc75d-0d04-0410-961f-82ee72b054a4>2012-08-14 16:45:55 +0000
commit6fe2a89d24424512af1d4474c2741481f92dd1cb (patch)
tree5c06ec0e03bb0ba229ec6bc79ac71362f4c78f3c /gcc/fortran/trans-expr.c
parenta63bcd97bbf68ea5df42a289da3ca5e1b5e471ab (diff)
downloadgcc-6fe2a89d24424512af1d4474c2741481f92dd1cb.tar.gz
fortran/
PR fortran/47586 * trans-expr.c (expr_is_variable): Handle regular, procedure pointer, and typebound functions returning a data pointer. testsuite/ PR fortran/47586 * gfortran.dg/typebound_proc_20.f90: Enable runtime test. * gfortran.dg/typebound_proc_27.f03: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190394 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 53fdf45c400..4f7d02620ad 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6961,6 +6961,8 @@ static bool
expr_is_variable (gfc_expr *expr)
{
gfc_expr *arg;
+ gfc_component *comp;
+ gfc_symbol *func_ifc;
if (expr->expr_type == EXPR_VARIABLE)
return true;
@@ -6972,7 +6974,50 @@ expr_is_variable (gfc_expr *expr)
return expr_is_variable (arg);
}
+ /* A data-pointer-returning function should be considered as a variable
+ too. */
+ if (expr->expr_type == EXPR_FUNCTION
+ && expr->ref == NULL)
+ {
+ if (expr->value.function.isym != NULL)
+ return false;
+
+ if (expr->value.function.esym != NULL)
+ {
+ func_ifc = expr->value.function.esym;
+ goto found_ifc;
+ }
+ else
+ {
+ gcc_assert (expr->symtree);
+ func_ifc = expr->symtree->n.sym;
+ goto found_ifc;
+ }
+
+ gcc_unreachable ();
+ }
+
+ comp = gfc_get_proc_ptr_comp (expr);
+ if ((expr->expr_type == EXPR_PPC || expr->expr_type == EXPR_FUNCTION)
+ && comp)
+ {
+ func_ifc = comp->ts.interface;
+ goto found_ifc;
+ }
+
+ if (expr->expr_type == EXPR_COMPCALL)
+ {
+ gcc_assert (!expr->value.compcall.tbp->is_generic);
+ func_ifc = expr->value.compcall.tbp->u.specific->n.sym;
+ goto found_ifc;
+ }
+
return false;
+
+found_ifc:
+ gcc_assert (func_ifc->attr.function
+ && func_ifc->result != NULL);
+ return func_ifc->result->attr.pointer;
}