aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2012-08-14 16:45:55 +0000
committerMikael Morin <mikael@gcc.gnu.org>2012-08-14 16:45:55 +0000
commitbbeffd6b40a97a661e78e10556a5b5f3edc4d78f (patch)
tree5c06ec0e03bb0ba229ec6bc79ac71362f4c78f3c /gcc/fortran/trans-expr.c
parentd7fee03dfcf056a7c77052327a2e5f9284ea271d (diff)
downloadgcc-bbeffd6b40a97a661e78e10556a5b5f3edc4d78f.zip
gcc-bbeffd6b40a97a661e78e10556a5b5f3edc4d78f.tar.gz
gcc-bbeffd6b40a97a661e78e10556a5b5f3edc4d78f.tar.bz2
re PR fortran/47586 ([F03] allocatable components: deep copy missing)
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. From-SVN: r190394
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 53fdf45..4f7d0262 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;
}