diff options
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index c1f5744..55c5fb2 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1872,6 +1872,12 @@ gimplify_conversion (tree *expr_p) canonicalize_addr_expr (expr_p); } + /* If we have a conversion to a non-register type force the + use of a VIEW_CONVERT_EXPR instead. */ + if (!is_gimple_reg_type (TREE_TYPE (*expr_p))) + *expr_p = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr_p), + TREE_OPERAND (*expr_p, 0)); + return GS_OK; } @@ -4555,20 +4561,31 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) /* Mark the RHS addressable. */ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, is_gimple_addressable, fb_either); - if (ret != GS_ERROR) - { - op0 = TREE_OPERAND (expr, 0); + if (ret == GS_ERROR) + break; - /* For various reasons, the gimplification of the expression - may have made a new INDIRECT_REF. */ - if (TREE_CODE (op0) == INDIRECT_REF) - goto do_indirect_ref; + /* We cannot rely on making the RHS addressable if it is + a temporary created by gimplification. In this case create a + new temporary that is initialized by a copy (which will + become a store after we mark it addressable). + This mostly happens if the frontend passed us something that + it could not mark addressable yet, like a fortran + pass-by-reference parameter (int) floatvar. */ + if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0))) + TREE_OPERAND (expr, 0) + = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p); - /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ - recompute_tree_invariant_for_addr_expr (expr); + op0 = TREE_OPERAND (expr, 0); - mark_addressable (TREE_OPERAND (expr, 0)); - } + /* For various reasons, the gimplification of the expression + may have made a new INDIRECT_REF. */ + if (TREE_CODE (op0) == INDIRECT_REF) + goto do_indirect_ref; + + /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ + recompute_tree_invariant_for_addr_expr (expr); + + mark_addressable (TREE_OPERAND (expr, 0)); break; } |