Reuse twice the same final procedure pointer expression instead of translating it twice. Final procedure pointer expressions were translated twice, once for the final procedure call, and once for the check for non-nullness (if applicable).
gcc/fortran/ChangeLog: * trans.cc (gfc_add_finalizer_call): Move pre and post code for the final procedure pointer expression to the outer block. Reuse the previously evaluated final procedure pointer expression. --- gcc/fortran/trans.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index 5c953a07533..3750d4eca82 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -1375,7 +1375,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_se final_se; gfc_init_se (&final_se, NULL); get_final_proc_ref (&final_se, final_expr); - gfc_add_block_to_block (&tmp_block, &final_se.pre); + gfc_add_block_to_block (block, &final_se.pre); gfc_se size_se; gfc_init_se (&size_se, NULL); @@ -1395,7 +1395,6 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) gfc_add_block_to_block (&tmp_block, &desc_se.post); gfc_add_block_to_block (&tmp_block, &size_se.post); - gfc_add_block_to_block (&tmp_block, &final_se.post); tmp = gfc_finish_block (&tmp_block); @@ -1404,11 +1403,10 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) tree cond; gfc_se se; - gfc_init_se (&se, NULL); - se.want_pointer = 1; - gfc_conv_expr (&se, final_expr); + tree ptr = gfc_build_addr_expr (NULL_TREE, final_se.expr); + cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, - se.expr, build_int_cst (TREE_TYPE (se.expr), 0)); + ptr, build_int_cst (TREE_TYPE (ptr), 0)); /* For CLASS(*) not only sym->_vtab->_final can be NULL but already sym->_vtab itself. */ @@ -1437,6 +1435,7 @@ gfc_add_finalizer_call (stmtblock_t *block, gfc_expr *expr2) } gfc_add_expr_to_block (block, tmp); + gfc_add_block_to_block (block, &final_se.post); return true; } -- 2.40.1