summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-29 19:26:47 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-29 19:26:47 +0000
commitc4aa078796bd9c7237e0ac5ea4ab7553106f199d (patch)
tree98a5e7f47a887d71b7ce051eac4583deee5a6dac /gcc/gimplify.c
parente34f5cd313173ac0144aeb70ab96e50fc36605ba (diff)
downloadgcc-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.c74
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);