diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-29 19:26:47 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-08-29 19:26:47 +0000 |
commit | c4aa078796bd9c7237e0ac5ea4ab7553106f199d (patch) | |
tree | 98a5e7f47a887d71b7ce051eac4583deee5a6dac /gcc/gimplify.c | |
parent | e34f5cd313173ac0144aeb70ab96e50fc36605ba (diff) | |
download | gcc-c4aa078796bd9c7237e0ac5ea4ab7553106f199d.tar.gz |
2009-08-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151199
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151206 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index dc8d0c089a4..7f1dc4ae94b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1763,7 +1763,8 @@ canonicalize_addr_expr (tree *expr_p) the expression pointer type. */ ddatype = TREE_TYPE (datype); pddatype = build_pointer_type (ddatype); - if (!useless_type_conversion_p (pddatype, ddatype)) + if (!useless_type_conversion_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)), + pddatype)) return; /* The lower bound and element sizes must be constant. */ @@ -1778,6 +1779,10 @@ canonicalize_addr_expr (tree *expr_p) TYPE_MIN_VALUE (TYPE_DOMAIN (datype)), NULL_TREE, NULL_TREE); *expr_p = build1 (ADDR_EXPR, pddatype, *expr_p); + + /* We can have stripped a required restrict qualifier above. */ + if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) + *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); } /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR. Remove it and/or other conversions @@ -3090,6 +3095,25 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) return ret; } +/* Prepare the node pointed to by EXPR_P, an is_gimple_addressable expression, + to be marked addressable. + + We cannot rely on such an expression being directly markable if a temporary + has been created by the gimplification. In this case, we create another + temporary and initialize it with a copy, which will become a store after we + mark it addressable. This can happen if the front-end passed us something + that it could not mark addressable yet, like a Fortran pass-by-reference + parameter (int) floatvar. */ + +static void +prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p) +{ + while (handled_component_p (*expr_p)) + expr_p = &TREE_OPERAND (*expr_p, 0); + if (is_gimple_reg (*expr_p)) + *expr_p = get_initialized_tmp_var (*expr_p, seq_p, NULL); +} + /* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with a call to __builtin_memcpy. */ @@ -3104,6 +3128,10 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value, to = TREE_OPERAND (*expr_p, 0); from = TREE_OPERAND (*expr_p, 1); + /* Mark the RHS addressable. Beware that it may not be possible to do so + directly if a temporary has been created by the gimplification. */ + prepare_gimple_addressable (&from, seq_p); + mark_addressable (from); from_ptr = build_fold_addr_expr_loc (loc, from); gimplify_arg (&from_ptr, seq_p, loc); @@ -4322,8 +4350,7 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* Insert pointer conversions required by the middle-end that are not required by the frontend. This fixes middle-end type checking for for example gcc.dg/redecl-6.c. */ - if (POINTER_TYPE_P (TREE_TYPE (*to_p)) - && lang_hooks.types_compatible_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p))) + if (POINTER_TYPE_P (TREE_TYPE (*to_p))) { STRIP_USELESS_TYPE_CONVERSION (*from_p); if (!useless_type_conversion_p (TREE_TYPE (*to_p), TREE_TYPE (*from_p))) @@ -4681,22 +4708,15 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make the implied temporary explicit. */ - /* Mark the RHS addressable. */ + /* Make the operand addressable. */ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p, is_gimple_addressable, fb_either); if (ret == GS_ERROR) break; - /* 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_reg (TREE_OPERAND (expr, 0))) - TREE_OPERAND (expr, 0) - = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p); + /* Then mark it. Beware that it may not be possible to do so directly + if a temporary has been created by the gimplification. */ + prepare_gimple_addressable (&TREE_OPERAND (expr, 0), pre_p); op0 = TREE_OPERAND (expr, 0); @@ -4705,10 +4725,22 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) if (TREE_CODE (op0) == INDIRECT_REF) goto do_indirect_ref; + mark_addressable (TREE_OPERAND (expr, 0)); + + /* The FEs may end up building ADDR_EXPRs early on a decl with + an incomplete type. Re-build ADDR_EXPRs in canonical form + here. */ + if (!types_compatible_p (TREE_TYPE (op0), TREE_TYPE (TREE_TYPE (expr)))) + *expr_p = build_fold_addr_expr (op0); + /* Make sure TREE_CONSTANT and TREE_SIDE_EFFECTS are set properly. */ - recompute_tree_invariant_for_addr_expr (expr); + recompute_tree_invariant_for_addr_expr (*expr_p); + + /* If we re-built the ADDR_EXPR add a conversion to the original type + if required. */ + if (!useless_type_conversion_p (TREE_TYPE (expr), TREE_TYPE (*expr_p))) + *expr_p = fold_convert (TREE_TYPE (expr), *expr_p); - mark_addressable (TREE_OPERAND (expr, 0)); break; } @@ -6148,12 +6180,7 @@ goa_lhs_expr_p (tree expr, tree addr) /* Also include casts to other type variants. The C front end is fond of adding these for e.g. volatile variables. This is like STRIP_TYPE_NOPS but includes the main variant lookup. */ - while ((CONVERT_EXPR_P (expr) - || TREE_CODE (expr) == NON_LVALUE_EXPR) - && TREE_OPERAND (expr, 0) != error_mark_node - && (TYPE_MAIN_VARIANT (TREE_TYPE (expr)) - == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0))))) - expr = TREE_OPERAND (expr, 0); + STRIP_USELESS_TYPE_CONVERSION (expr); if (TREE_CODE (expr) == INDIRECT_REF) { @@ -6162,8 +6189,7 @@ goa_lhs_expr_p (tree expr, tree addr) && (CONVERT_EXPR_P (expr) || TREE_CODE (expr) == NON_LVALUE_EXPR) && TREE_CODE (expr) == TREE_CODE (addr) - && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) - == TYPE_MAIN_VARIANT (TREE_TYPE (addr))) + && types_compatible_p (TREE_TYPE (expr), TREE_TYPE (addr))) { expr = TREE_OPERAND (expr, 0); addr = TREE_OPERAND (addr, 0); |