c-typeck.c (build_function_call): Set fundecl = function again.
authorDaniel Berlin <dberlin@dberlin.org>
Tue, 21 Jun 2005 00:59:17 +0000 (00:59 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Tue, 21 Jun 2005 00:59:17 +0000 (00:59 +0000)
2005-06-20  Daniel Berlin  <dberlin@dberlin.org>

* c-typeck.c (build_function_call): Set fundecl = function again.
* tree-ssa-alias.c (find_used_portions): Address taking causes the
entire variable to be used.
* tree-ssa-structalias.c (do_structure_copy): Fix handling of
unknown size variables, and structure copies from addressof
operations.  Simplify how we do *a = *b type structure copies.
(init_base_vars): Add ANYTHING = &ANYTHING constraint the right
way.  READONLY's address is not taken by default.
INTEGER dereference should point to anything.
(create_variable_info_for): It's okay for the first field to not start
at 0.

From-SVN: r101227

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/gcc.c-torture/compile/pta-1.c [new file with mode: 0644]
gcc/tree-ssa-alias.c
gcc/tree-ssa-structalias.c

index 06dc476ad894a813f3ac36197bce41d17cb1d396..01132011cba63a25a9d634d18b1020d31f134f07 100644 (file)
@@ -1,3 +1,17 @@
+2005-06-20  Daniel Berlin  <dberlin@dberlin.org>
+
+       * c-typeck.c (build_function_call): Set fundecl = function again.
+       * tree-ssa-alias.c (find_used_portions): Address taking causes the
+       entire variable to be used.
+       * tree-ssa-structalias.c (do_structure_copy): Fix handling of
+       unknown size variables, and structure copies from addressof
+       operations.  Simplify how we do *a = *b type structure copies.
+       (init_base_vars): Add ANYTHING = &ANYTHING constraint the right
+       way.  READONLY's address is not taken by default.
+       INTEGER dereference should point to anything.
+       (create_variable_info_for): It's okay for the first field to not start
+       at 0.
+
 2005-06-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        config/sh/linux.h (FUNCTION_PROFILER): Constify a char*.
index 988d958e911a3ffcb2f08a86febfbd818e886f4b..7f462c4fff7ffeb8245531eeb5cc394922091bb4 100644 (file)
@@ -1990,6 +1990,7 @@ build_function_call (tree function, tree params)
        return tem;
 
       name = DECL_NAME (function);
+      fundecl = function;
     }
   function = default_function_array_conversion (function);
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pta-1.c b/gcc/testsuite/gcc.c-torture/compile/pta-1.c
new file mode 100644 (file)
index 0000000..515e5ff
--- /dev/null
@@ -0,0 +1,31 @@
+typedef struct JSObject JSObject;
+typedef struct JSObjectMap *(*JSNewObjectMapOp) (JSObject *obj);
+typedef JSObject *(*JSGetMethodOp) (JSObject *obj);
+struct JSObjectOps {
+    JSNewObjectMapOp newObjectMap;
+};
+struct JSXMLObjectOps {
+    struct JSObjectOps base;
+    JSGetMethodOp getMethod;
+};
+struct JSObjectMap {
+    struct JSObjectOps *ops;
+};
+struct JSObject {
+    struct JSObjectMap *map;
+};
+
+struct JSXMLObjectOps js_XMLObjectOps;
+
+
+/* We need to create SFT's for the entire structure when this address is taken, 
+   not just the part in the component reference itself.  */
+JSObject *JS_GetMethod(JSObject *obj)
+{
+    if (obj->map->ops == &js_XMLObjectOps.base) {
+        struct JSXMLObjectOps *ops;
+        ops = (struct JSXMLObjectOps *) obj->map->ops;
+        obj = ops->getMethod(obj);
+    }
+    return obj;
+}
index 3098549d881dddddfe96cce4a3286f4d97dd5433..04125cac88c1527e7bc5cfc2390fec67f8e041b8 100644 (file)
@@ -3119,6 +3119,35 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
          }
       }
       break;
+      /* This is here to make sure we mark the entire base variable as used
+        when you take its address.  Because our used portion analysis is
+        simple, we aren't looking at casts or pointer arithmetic to see what
+        happens when you take the address.  */
+    case ADDR_EXPR:
+      {
+       tree var = get_base_address (TREE_OPERAND (*tp, 0));
+
+       if (var 
+           && DECL_P (var)
+           && DECL_SIZE (var)
+           && var_can_have_subvars (var)
+           && TREE_CODE (DECL_SIZE (var)) == INTEGER_CST)
+         {
+           used_part_t up;
+           size_t uid = var_ann (var)->uid;        
+           
+           up = get_or_create_used_part_for (uid);
+           up->minused = 0;
+           up->maxused = TREE_INT_CST_LOW (DECL_SIZE (var));
+           up->implicit_uses = true;
+
+           used_portions[uid] = up;
+           *walk_subtrees = 0;
+           return NULL_TREE;
+         }
+      }
+      break;
     case VAR_DECL:
     case PARM_DECL:
       {
index 5ca2a5cc98ff15202d64cf2553fded726eb5fb39..4aeda117cb2442a7b857176641c7fea601224a34 100644 (file)
@@ -2210,8 +2210,7 @@ do_simple_structure_copy (const struct constraint_expr lhs,
                          const unsigned HOST_WIDE_INT size)
 {
   varinfo_t p = get_varinfo (lhs.var);
-  unsigned HOST_WIDE_INT pstart,last;
-
+  unsigned HOST_WIDE_INT pstart, last;
   pstart = p->offset;
   last = p->offset + size;
   for (; p && p->offset < last; p = p->next)
@@ -2321,8 +2320,6 @@ do_structure_copy (tree lhsop, tree rhsop)
   unsigned HOST_WIDE_INT lhssize;
   unsigned HOST_WIDE_INT rhssize;
 
-  lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
-  rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
   lhs = get_constraint_for (lhsop);  
   rhs = get_constraint_for (rhsop);
   
@@ -2334,8 +2331,18 @@ do_structure_copy (tree lhsop, tree rhsop)
       rhs = tmp;
     }
   
-  /* If the RHS is a special var, set all the LHS fields to that
-     special var.  */
+  /*  This is fairly conservative for the RHS == ADDRESSOF case, in that it's
+      possible it's something we could handle.  However, most cases falling
+      into this are dealing with transparent unions, which are slightly
+      weird. */
+  if (rhs.type == ADDRESSOF && rhs.var > integer_id)
+    {
+      rhs.type = ADDRESSOF;
+      rhs.var = anything_id;
+    }
+
+  /* If the RHS is a special var, or an addressof, set all the LHS fields to
+     that special var.  */
   if (rhs.var <= integer_id)
     {
       for (p = get_varinfo (lhs.var); p; p = p->next)
@@ -2351,6 +2358,20 @@ do_structure_copy (tree lhsop, tree rhsop)
     }
   else
     {
+      /* The size only really matters insofar as we don't set more or less of
+        the variable.  If we hit an unknown size var, the size should be the
+        whole darn thing.  */
+      if (get_varinfo (rhs.var)->is_unknown_size_var)
+       rhssize = ~0;
+      else
+       rhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (rhsop)));
+
+      if (get_varinfo (lhs.var)->is_unknown_size_var)
+       lhssize = ~0;
+      else
+       lhssize = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (lhsop)));
+
+  
       if (rhs.type == SCALAR && lhs.type == SCALAR)  
        do_simple_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
       else if (lhs.type != DEREF && rhs.type == DEREF)
@@ -2362,14 +2383,12 @@ do_structure_copy (tree lhsop, tree rhsop)
          tree rhsdecl = get_varinfo (rhs.var)->decl;
          tree pointertype = TREE_TYPE (rhsdecl);
          tree pointedtotype = TREE_TYPE (pointertype);
-         tree tmpvar;
+         tree tmpvar;  
+
          gcc_assert (rhs.type == DEREF && lhs.type == DEREF);
          tmpvar = create_tmp_var_raw (pointedtotype, "structcopydereftmp");
-         lhs = get_constraint_for (tmpvar);
-         do_rhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
-         rhs = lhs;
-         lhs = get_constraint_for (lhsop);
-         do_lhs_deref_structure_copy (lhs, rhs, MIN (lhssize, rhssize));
+         do_structure_copy (tmpvar, rhsop);
+         do_structure_copy (lhsop, tmpvar);
        }
     }
 }
@@ -2723,7 +2742,7 @@ create_variable_info_for (tree decl, const char *name)
   vi->offset = 0;
   vi->has_union = hasunion;
   if (!TYPE_SIZE (decltype) 
-      || TREE_CODE (TYPE_SIZE  (decltype)) != INTEGER_CST
+      || TREE_CODE (TYPE_SIZE (decltype)) != INTEGER_CST
       || TREE_CODE (decltype) == ARRAY_TYPE
       || TREE_CODE (decltype) == UNION_TYPE
       || TREE_CODE (decltype) == QUAL_UNION_TYPE)
@@ -2786,7 +2805,6 @@ create_variable_info_for (tree decl, const char *name)
        }
       
       field = fo->field;
-      gcc_assert (bitpos_of_field (field) == 0);
       vi->size = TREE_INT_CST_LOW (DECL_SIZE (field));
       for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
        {
@@ -3049,8 +3067,10 @@ init_base_vars (void)
   rhs.var = anything_id;
   rhs.offset = 0;
   var_anything->address_taken = true;
-  process_constraint (new_constraint (lhs, rhs));
-
+  /* This specifically does not use process_constraint because
+     process_constraint ignores all anything = anything constraints, since all
+     but this one are redundant.  */
+  VEC_safe_push (constraint_t, gc, constraints, new_constraint (lhs, rhs));
   
   /* Create the READONLY variable, used to represent that a variable
      points to readonly memory.  */
@@ -3075,7 +3095,6 @@ init_base_vars (void)
   rhs.type = ADDRESSOF;
   rhs.var = anything_id;
   rhs.offset = 0;
-  var_readonly->address_taken = true;
   
   process_constraint (new_constraint (lhs, rhs));
   
@@ -3091,6 +3110,16 @@ init_base_vars (void)
   var_integer->next = NULL;
   integer_id = 3;
   VEC_safe_push (varinfo_t, gc, varmap, var_integer);
+
+  /* *INTEGER = ANYTHING, because we don't know where a dereference of a random
+     integer will point to.  */
+  lhs.type = SCALAR;
+  lhs.var = integer_id;
+  lhs.offset = 0;
+  rhs.type = ADDRESSOF;
+  rhs.var = anything_id;
+  rhs.offset = 0;
+  process_constraint (new_constraint (lhs, rhs));
 }  
 
 
@@ -3101,7 +3130,6 @@ static void
 create_alias_vars (void)
 {
   basic_block bb;
-
   
   init_alias_vars ();