aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-09-16 11:06:25 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-09-16 11:06:25 +0000
commited6c4831a9aca4764b45734ae31c9f6e8eac4cac (patch)
tree0668baf35a808838597ae97ba541f699d53e4a0e /gcc
parentff802fa1f343ad103f939306af07337d9562f1f3 (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr45623.c28
-rw-r--r--gcc/tree-ssa-structalias.c83
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;