OSDN Git Service

2010-09-16 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Sep 2010 11:06:25 +0000 (11:06 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Sep 2010 11:06:25 +0000 (11:06 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164333 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr45623.c [new file with mode: 0644]
gcc/tree-ssa-structalias.c

index 2730b6a..bfaed4f 100644 (file)
@@ -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.
index c3360f3..8baa140 100644 (file)
@@ -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 (file)
index 0000000..2f07d25
--- /dev/null
@@ -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;
+}
index ef09014..486e9b3 100644 (file)
@@ -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;