diff options
author | Mikael Morin <mikael@gcc.gnu.org> | 2012-08-14 16:45:55 +0000 |
---|---|---|
committer | Mikael Morin <mikael@gcc.gnu.org> | 2012-08-14 16:45:55 +0000 |
commit | bbeffd6b40a97a661e78e10556a5b5f3edc4d78f (patch) | |
tree | 5c06ec0e03bb0ba229ec6bc79ac71362f4c78f3c /gcc/fortran/trans-expr.c | |
parent | d7fee03dfcf056a7c77052327a2e5f9284ea271d (diff) | |
download | gcc-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.c | 45 |
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; } |