http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54603
--- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> 2012-09-16 20:53:30 UTC --- For this%a = ext_ptr(this%a%init,this%a%cleanup) and the code (in trans-expr.c) 5584 gfc_conv_expr (&se, expr); ... 5588 tmp = gfc_trans_scalar_assign (&lse, &se, cm->ts, true, false, true); we have (gdb) p debug_tree (se.expr) <parm_decl 0x2aaaac288380 init type <pointer_type 0x2aaaac2a2888 type <pointer_type 0x2aaaac29f1f8 type <function_type 0x2aaaac29f150> which is one "pointer_type" too much. That's fixed by using: if (gfc_expr_attr (expr).proc_pointer) se.expr = gfc_build_addr_expr (NULL_TREE, se.expr); However, that will fail for this%a = ext_ptr(init, cleanup) as those have already too much indirection. The following patch works, but I think the proper fix has to be in gfc_conv_variable/gfc_conv_ref. --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -5584,2 +5584,9 @@ gfc_trans_subcomponent_assign (tree dest, gfc_conv_expr (&se, expr); + if (gfc_expr_attr (expr).proc_pointer) + { + if (expr->symtree->n.sym->attr.dummy && !expr->ref) + se.expr = build_fold_indirect_ref_loc (input_location, se.expr); + else + se.expr = gfc_build_addr_expr (NULL_TREE, se.expr); + } if (cm->ts.type == BT_CHARACTER)