OSDN Git Service

gcc/objc/Changelog:
[pf3gnuchains/gcc-fork.git] / gcc / tree-object-size.c
index 5c64b98..35b3c44 100644 (file)
@@ -1,5 +1,5 @@
 /* __builtin_object_size (ptr, object_size_type) computation
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>
 
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "toplev.h"
 #include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-ssa-propagate.h"
@@ -171,9 +173,9 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
     {
       unsigned HOST_WIDE_INT sz;
 
-      if (!osi)
+      if (!osi || (object_size_type & 1) != 0)
        sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
-                                         object_size_type);
+                                         object_size_type & ~1);
       else
        {
          tree var = TREE_OPERAND (pt_var, 0);
@@ -217,7 +219,7 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
                 && TREE_CODE (var) != IMAGPART_EXPR)
            var = TREE_OPERAND (var, 0);
          if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
-             var = TREE_OPERAND (var, 0);
+           var = TREE_OPERAND (var, 0);
          if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
              || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
              || (pt_var_size
@@ -262,8 +264,17 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
                        v = NULL_TREE;
                        break;
                      }
-                   if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
-                        == RECORD_TYPE)
+                   while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+                     if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                         != UNION_TYPE
+                         && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                         != QUAL_UNION_TYPE)
+                       break;
+                     else
+                       v = TREE_OPERAND (v, 0);
+                   if (TREE_CODE (v) == COMPONENT_REF
+                       && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                          == RECORD_TYPE)
                      {
                        tree fld_chain = TREE_CHAIN (TREE_OPERAND (v, 1));
                        for (; fld_chain; fld_chain = TREE_CHAIN (fld_chain))
@@ -275,18 +286,17 @@ addr_object_size (struct object_size_info *osi, const_tree ptr,
                            v = NULL_TREE;
                            break;
                          }
+                       v = TREE_OPERAND (v, 0);
                      }
-
-                   if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
-                       == RECORD_TYPE)
-                     v = TREE_OPERAND (v, 0);
-                   while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
-                     if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
-                         && TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
+                   while (v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+                     if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                         != UNION_TYPE
+                         && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+                         != QUAL_UNION_TYPE)
                        break;
                      else
                        v = TREE_OPERAND (v, 0);
-                   if (v && v != pt_var)
+                   if (v != pt_var)
                      v = NULL_TREE;
                    else
                      v = pt_var;
@@ -373,7 +383,7 @@ alloc_object_size (const_gimple call, int object_size_type)
       if (TREE_CHAIN (p))
         arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
     }
+
   if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
     switch (DECL_FUNCTION_CODE (callee))
       {
@@ -389,10 +399,10 @@ alloc_object_size (const_gimple call, int object_size_type)
 
   if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call)
       || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST
-      || (arg2 >= 0 
+      || (arg2 >= 0
          && (arg2 >= (int)gimple_call_num_args (call)
              || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST)))
-    return unknown[object_size_type];    
+    return unknown[object_size_type];
 
   if (arg2 >= 0)
     bytes = size_binop (MULT_EXPR,
@@ -1103,7 +1113,7 @@ check_for_plus_in_loops (struct object_size_info *osi, tree var)
     {
       tree basevar = gimple_assign_rhs1 (stmt);
       tree cst = gimple_assign_rhs2 (stmt);
-           
+
       gcc_assert (TREE_CODE (cst) == INTEGER_CST);
 
       if (integer_zerop (cst))
@@ -1195,7 +1205,8 @@ compute_object_sizes (void)
                        result = fold_convert (size_type_node,
                                               integer_minus_one_node);
                      else if (object_size_type < 4)
-                       result = size_zero_node;
+                       result = fold_convert (size_type_node,
+                                              integer_zero_node);
                    }
                }