diff options
author | Richard Guenther <rguenther@suse.de> | 2010-09-16 11:06:25 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-09-16 11:06:25 +0000 |
commit | ed6c4831a9aca4764b45734ae31c9f6e8eac4cac (patch) | |
tree | 0668baf35a808838597ae97ba541f699d53e4a0e /gcc | |
parent | ff802fa1f343ad103f939306af07337d9562f1f3 (diff) | |
download | gcc-ed6c4831a9aca4764b45734ae31c9f6e8eac4cac.zip gcc-ed6c4831a9aca4764b45734ae31c9f6e8eac4cac.tar.gz gcc-ed6c4831a9aca4764b45734ae31c9f6e8eac4cac.tar.bz2 |
re PR tree-optimization/45623 (GCC 4.5.[01] breaks our ffi on Linux64. ABI break?)
2010-09-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45623
* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
(get_constraint_for_component_ref): If computing a constraint
for the rhs handle type punning through unions.
(get_constraint_for_address_of): Adjust.
(get_constraint_for_1): Likewise.
(get_constraint_for): Likewise.
(get_constraint_for_rhs): New function.
(do_structure_copy): Adjust.
(make_constraint_to): Likewise.
(handle_const_call): Likewise.
(find_func_aliases): Likewise.
(process_ipa_clobber): Likewise.
(create_variable_info_for): Likewise.
* gcc.dg/torture/pr45623.c: New testcase.
From-SVN: r164333
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr45623.c | 28 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 83 |
4 files changed, 110 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2730b6a..bfaed4f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2010-09-16 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/45623 + * tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust. + (get_constraint_for_component_ref): If computing a constraint + for the rhs handle type punning through unions. + (get_constraint_for_address_of): Adjust. + (get_constraint_for_1): Likewise. + (get_constraint_for): Likewise. + (get_constraint_for_rhs): New function. + (do_structure_copy): Adjust. + (make_constraint_to): Likewise. + (handle_const_call): Likewise. + (find_func_aliases): Likewise. + (process_ipa_clobber): Likewise. + (create_variable_info_for): Likewise. + 2010-09-16 Ira Rosen <irar@il.ibm.com> * tree-vectorizer.c: Fix documentation. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c3360f3..8baa140 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-16 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/45623 + * gcc.dg/torture/pr45623.c: New testcase. + 2010-09-16 Ira Rosen <irar@il.ibm.com> * gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function diff --git a/gcc/testsuite/gcc.dg/torture/pr45623.c b/gcc/testsuite/gcc.dg/torture/pr45623.c new file mode 100644 index 0000000..2f07d25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr45623.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ + +#include <stdint.h> + +extern void abort (void); + +char *s1 = "foo"; +char *s2 = "bar"; + +char **ss1 = &s1; + +typedef union jsval_layout +{ + uint64_t asBits; + char **ptr; +} jsval_layout; + +int main() +{ + jsval_layout l, m; + l.ptr = ss1; + m.asBits = l.asBits; + char ** data = m.ptr; + *data = s2; + if (s1 != s2) + abort (); + return 0; +} diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index ef09014..486e9b3 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -532,8 +532,9 @@ struct constraint_expr typedef struct constraint_expr ce_s; DEF_VEC_O(ce_s); DEF_VEC_ALLOC_O(ce_s, heap); -static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool); +static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool, bool); static void get_constraint_for (tree, VEC(ce_s, heap) **); +static void get_constraint_for_rhs (tree, VEC(ce_s, heap) **); static void do_deref (VEC (ce_s, heap) **); /* Our set constraints are made up of two constraint expressions, one @@ -2994,7 +2995,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, does not change the points-to solution. */ if (!use_field_sensitive) { - get_constraint_for (ptr, results); + get_constraint_for_rhs (ptr, results); return; } @@ -3014,7 +3015,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, rhsoffset = UNKNOWN_OFFSET; } - get_constraint_for (ptr, results); + get_constraint_for_rhs (ptr, results); if (rhsoffset == 0) return; @@ -3092,11 +3093,13 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, /* Given a COMPONENT_REF T, return the constraint_expr vector for it. - If address_p is true the result will be taken its address of. */ + If address_p is true the result will be taken its address of. + If lhs_p is true then the constraint expression is assumed to be used + as the lhs. */ static void get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, - bool address_p) + bool address_p, bool lhs_p) { tree orig_t = t; HOST_WIDE_INT bitsize = -1; @@ -3124,11 +3127,34 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, return; } + /* Handle type-punning through unions. If we are extracting a pointer + from a union via a possibly type-punning access that pointer + points to anything, similar to a conversion of an integer to + a pointer. */ + if (!lhs_p) + { + tree u; + for (u = t; + TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; + u = TREE_OPERAND (u, 0)) + if (TREE_CODE (u) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) + { + struct constraint_expr temp; + + temp.offset = 0; + temp.var = anything_id; + temp.type = ADDRESSOF; + VEC_safe_push (ce_s, heap, *results, &temp); + return; + } + } + t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize); /* Pretend to take the address of the base, we'll take care of adding the required subset of sub-fields below. */ - get_constraint_for_1 (t, results, true); + get_constraint_for_1 (t, results, true, lhs_p); gcc_assert (VEC_length (ce_s, *results) == 1); result = VEC_last (ce_s, *results); @@ -3257,8 +3283,6 @@ do_deref (VEC (ce_s, heap) **constraints) } } -static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool); - /* Given a tree T, return the constraint expression for taking the address of it. */ @@ -3268,7 +3292,7 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results) struct constraint_expr *c; unsigned int i; - get_constraint_for_1 (t, results, true); + get_constraint_for_1 (t, results, true, true); FOR_EACH_VEC_ELT (ce_s, *results, i, c) { @@ -3282,7 +3306,8 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results) /* Given a tree T, return the constraint expression for it. */ static void -get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) +get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p, + bool lhs_p) { struct constraint_expr temp; @@ -3354,10 +3379,11 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) case ARRAY_REF: case ARRAY_RANGE_REF: case COMPONENT_REF: - get_constraint_for_component_ref (t, results, address_p); + get_constraint_for_component_ref (t, results, address_p, lhs_p); return; case VIEW_CONVERT_EXPR: - get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p); + get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p, + lhs_p); return; /* We are missing handling for TARGET_MEM_REF here. */ default:; @@ -3382,7 +3408,7 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) { struct constraint_expr *rhsp; unsigned j; - get_constraint_for_1 (val, &tmp, address_p); + get_constraint_for_1 (val, &tmp, address_p, lhs_p); FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp) VEC_safe_push (ce_s, heap, *results, rhsp); VEC_truncate (ce_s, tmp, 0); @@ -3419,7 +3445,18 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results) { gcc_assert (VEC_length (ce_s, *results) == 0); - get_constraint_for_1 (t, results, false); + get_constraint_for_1 (t, results, false, true); +} + +/* Given a gimple tree T, return the constraint expression vector for it + to be used as the rhs of a constraint. */ + +static void +get_constraint_for_rhs (tree t, VEC (ce_s, heap) **results) +{ + gcc_assert (VEC_length (ce_s, *results) == 0); + + get_constraint_for_1 (t, results, false, false); } @@ -3461,7 +3498,7 @@ do_structure_copy (tree lhsop, tree rhsop) unsigned j; get_constraint_for (lhsop, &lhsc); - get_constraint_for (rhsop, &rhsc); + get_constraint_for_rhs (rhsop, &rhsc); lhsp = VEC_index (ce_s, lhsc, 0); rhsp = VEC_index (ce_s, rhsc, 0); if (lhsp->type == DEREF @@ -3531,7 +3568,7 @@ make_constraint_to (unsigned id, tree op) includes.offset = 0; includes.type = SCALAR; - get_constraint_for (op, &rhsc); + get_constraint_for_rhs (op, &rhsc); FOR_EACH_VEC_ELT (ce_s, rhsc, j, c) process_constraint (new_constraint (includes, *c)); VEC_free (ce_s, heap, rhsc); @@ -3904,7 +3941,7 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results) VEC(ce_s, heap) *argc = NULL; unsigned i; struct constraint_expr *argp; - get_constraint_for (arg, &argc); + get_constraint_for_rhs (arg, &argc); FOR_EACH_VEC_ELT (ce_s, argc, i, argp) VEC_safe_push (ce_s, heap, *results, argp); VEC_free(ce_s, heap, argc); @@ -4038,7 +4075,7 @@ find_func_aliases (gimple origt) tree strippedrhs = PHI_ARG_DEF (t, i); STRIP_NOPS (strippedrhs); - get_constraint_for (gimple_phi_arg_def (t, i), &rhsc); + get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc); FOR_EACH_VEC_ELT (ce_s, lhsc, j, c) { @@ -4322,7 +4359,7 @@ find_func_aliases (gimple origt) if (!could_have_pointers (arg)) continue; - get_constraint_for (arg, &rhsc); + get_constraint_for_rhs (arg, &rhsc); lhs = get_function_part_constraint (fi, fi_parm_base + j); while (VEC_length (ce_s, rhsc) != 0) { @@ -4417,7 +4454,7 @@ find_func_aliases (gimple origt) && !(POINTER_TYPE_P (gimple_expr_type (t)) && !POINTER_TYPE_P (TREE_TYPE (rhsop)))) || gimple_assign_single_p (t)) - get_constraint_for (rhsop, &rhsc); + get_constraint_for_rhs (rhsop, &rhsc); else { temp.type = ADDRESSOF; @@ -4468,7 +4505,7 @@ find_func_aliases (gimple origt) unsigned i; lhs = get_function_part_constraint (fi, fi_result); - get_constraint_for (gimple_return_retval (t), &rhsc); + get_constraint_for_rhs (gimple_return_retval (t), &rhsc); FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp) process_constraint (new_constraint (lhs, *rhsp)); } @@ -4549,7 +4586,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr) VEC(ce_s, heap) *ptrc = NULL; struct constraint_expr *c, lhs; unsigned i; - get_constraint_for (ptr, &ptrc); + get_constraint_for_rhs (ptr, &ptrc); lhs = get_function_part_constraint (fi, fi_clobbers); FOR_EACH_VEC_ELT (ce_s, ptrc, i, c) process_constraint (new_constraint (lhs, *c)); @@ -5430,7 +5467,7 @@ create_variable_info_for (tree decl, const char *name) VEC (ce_s, heap) *rhsc = NULL; struct constraint_expr lhs, *rhsp; unsigned i; - get_constraint_for (DECL_INITIAL (decl), &rhsc); + get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc); lhs.var = vi->id; lhs.offset = 0; lhs.type = SCALAR; |