OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / tree-mudflap.c
index d1dad3a..e4f6ec0 100644 (file)
@@ -1,5 +1,5 @@
 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
    Free Software Foundation, Inc.
    Contributed by Frank Ch. Eigler <fche@redhat.com>
    and Graydon Hoare <graydon@redhat.com>
@@ -39,11 +39,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "hashtab.h"
 #include "diagnostic.h"
-#include <demangle.h>
+#include "demangle.h"
 #include "langhooks.h"
 #include "ggc.h"
 #include "cgraph.h"
-#include "toplev.h"
 #include "gimple.h"
 
 /* Internal function decls */
@@ -70,6 +69,13 @@ static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *,
 static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
 static unsigned int execute_mudflap_function_decls (void);
 
+/* Return true if DECL is artificial stub that shouldn't be instrumented by
+   mf.  We should instrument clones of non-artificial functions.  */
+static inline bool
+mf_artificial (const_tree decl)
+{
+  return DECL_ARTIFICIAL (DECL_ORIGIN (decl));
+}
 
 /* ------------------------------------------------------------------------ */
 /* Some generally helpful functions for mudflap instrumentation.  */
@@ -82,7 +88,7 @@ mf_build_string (const char *string)
   tree result = mf_mark (build_string (len + 1, string));
 
   TREE_TYPE (result) = build_array_type
-    (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
+    (char_type_node, build_index_type (size_int (len)));
   TREE_CONSTANT (result) = 1;
   TREE_READONLY (result) = 1;
   TREE_STATIC (result) = 1;
@@ -322,7 +328,7 @@ mf_make_mf_cache_struct_type (tree field_type)
   tree struct_type = make_node (RECORD_TYPE);
   DECL_CONTEXT (fieldlo) = struct_type;
   DECL_CONTEXT (fieldhi) = struct_type;
-  TREE_CHAIN (fieldlo) = fieldhi;
+  DECL_CHAIN (fieldlo) = fieldhi;
   TYPE_FIELDS (struct_type) = fieldlo;
   TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
   layout_type (struct_type);
@@ -413,12 +419,16 @@ execute_mudflap_function_ops (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
 
+  add_referenced_var (mf_cache_array_decl);
+  add_referenced_var (mf_cache_shift_decl);
+  add_referenced_var (mf_cache_mask_decl);
+
   /* In multithreaded mode, don't cache the lookup cache parameters.  */
   if (! flag_mudflap_threads)
     mf_decl_cache_locals ();
@@ -622,7 +632,7 @@ mf_build_check_statement_for (tree base, tree limit,
 
   u = build3 (COMPONENT_REF, mf_uintptr_type,
               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
-              TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
+              DECL_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
 
   v = mf_limit;
 
@@ -790,7 +800,8 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
               }
             else if (TREE_CODE (var) == COMPONENT_REF)
               var = TREE_OPERAND (var, 0);
-            else if (INDIRECT_REF_P (var))
+            else if (INDIRECT_REF_P (var)
+                    || TREE_CODE (var) == MEM_REF)
               {
                base = TREE_OPERAND (var, 0);
                 break;
@@ -843,16 +854,15 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
              elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
                            elt);
             addr = fold_convert_loc (location, ptr_type_node, elt ? elt : base);
-            addr = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node,
-                               addr, fold_convert_loc (location, sizetype,
-                                                       byte_position (field)));
+            addr = fold_build_pointer_plus_loc (location,
+                                               addr, byte_position (field));
           }
         else
           addr = build1 (ADDR_EXPR, build_pointer_type (type), t);
 
         limit = fold_build2_loc (location, MINUS_EXPR, mf_uintptr_type,
                              fold_build2_loc (location, PLUS_EXPR, mf_uintptr_type,
-                                         convert (mf_uintptr_type, addr),
+                                         fold_convert (mf_uintptr_type, addr),
                                          size),
                              integer_one_node);
       }
@@ -861,21 +871,25 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
     case INDIRECT_REF:
       addr = TREE_OPERAND (t, 0);
       base = addr;
-      limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node,
-                          fold_build2_loc (location,
-                                       POINTER_PLUS_EXPR, ptr_type_node, base,
-                                       size),
-                          size_int (-1));
+      limit = fold_build_pointer_plus_hwi_loc
+       (location, fold_build_pointer_plus_loc (location, base, size), -1);
+      break;
+
+    case MEM_REF:
+      addr = fold_build_pointer_plus_loc (location, TREE_OPERAND (t, 0),
+                                         TREE_OPERAND (t, 1));
+      base = addr;
+      limit = fold_build_pointer_plus_hwi_loc (location,
+                          fold_build_pointer_plus_loc (location,
+                                                       base, size), -1);
       break;
 
     case TARGET_MEM_REF:
       addr = tree_mem_ref_addr (ptr_type_node, t);
       base = addr;
-      limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node,
-                          fold_build2_loc (location,
-                                       POINTER_PLUS_EXPR, ptr_type_node, base,
-                                       size),
-                          size_int (-1));
+      limit = fold_build_pointer_plus_hwi_loc (location,
+                          fold_build_pointer_plus_loc (location,
+                                                       base, size), -1);
       break;
 
     case ARRAY_RANGE_REF:
@@ -894,29 +908,23 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
           return;
 
         bpu = bitsize_int (BITS_PER_UNIT);
-        ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
+        ofs = fold_convert (bitsizetype, TREE_OPERAND (t, 2));
         rem = size_binop_loc (location, TRUNC_MOD_EXPR, ofs, bpu);
-        ofs = fold_convert_loc (location,
-                               sizetype,
-                               size_binop_loc (location,
-                                               TRUNC_DIV_EXPR, ofs, bpu));
+        ofs = size_binop_loc (location, TRUNC_DIV_EXPR, ofs, bpu);
 
-        size = convert (bitsizetype, TREE_OPERAND (t, 1));
+        size = fold_convert (bitsizetype, TREE_OPERAND (t, 1));
         size = size_binop_loc (location, PLUS_EXPR, size, rem);
         size = size_binop_loc (location, CEIL_DIV_EXPR, size, bpu);
-        size = convert (sizetype, size);
+        size = fold_convert (sizetype, size);
 
         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
-        addr = convert (ptr_type_node, addr);
-        addr = fold_build2_loc (location, POINTER_PLUS_EXPR,
-                           ptr_type_node, addr, ofs);
+        addr = fold_convert (ptr_type_node, addr);
+        addr = fold_build_pointer_plus_loc (location, addr, ofs);
 
         base = addr;
-        limit = fold_build2_loc (location, POINTER_PLUS_EXPR, ptr_type_node,
-                             fold_build2_loc (location,
-                                         POINTER_PLUS_EXPR, ptr_type_node,
-                                          base, size),
-                             size_int (-1));
+        limit = fold_build_pointer_plus_hwi_loc (location,
+                             fold_build_pointer_plus_loc (location,
+                                                         base, size), -1);
       }
       break;
 
@@ -928,7 +936,6 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
 }
 /* Transform
    1) Memory references.
-   2) BUILTIN_ALLOCA calls.
 */
 static void
 mf_xform_statements (void)
@@ -969,14 +976,6 @@ mf_xform_statements (void)
                 }
               break;
 
-            case GIMPLE_CALL:
-              {
-                tree fndecl = gimple_call_fndecl (s);
-                if (fndecl && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA))
-                  gimple_call_set_cannot_inline (s, true);
-              }
-              break;
-
             default:
               ;
             }
@@ -1002,8 +1001,8 @@ execute_mudflap_function_decls (void)
 
   /* Don't instrument functions such as the synthetic constructor
      built during mudflap_finish_file.  */
-  if (mf_marked_p (current_function_decl) ||
-      DECL_ARTIFICIAL (current_function_decl))
+  if (mf_marked_p (current_function_decl)
+      || mf_artificial (current_function_decl))
     return 0;
 
   push_gimplify_context (&gctx);
@@ -1049,7 +1048,8 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
 
          /* Variable-sized objects should have sizes already been
             gimplified when we got here. */
-         size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
+         size = fold_convert (size_type_node,
+                              TYPE_SIZE_UNIT (TREE_TYPE (decl)));
          gcc_assert (is_gimple_val (size));
 
 
@@ -1061,7 +1061,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
           unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3,
                                                 unregister_fncall_param,
                                                 size,
-                                                build_int_cst (NULL_TREE, 3));
+                                                integer_three_node);
 
 
           variable_name = mf_varname_tree (decl);
@@ -1074,7 +1074,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
          register_fncall = gimple_build_call (mf_register_fndecl, 4,
                                               register_fncall_param,
                                               size,
-                                              build_int_cst (NULL_TREE, 3),
+                                              integer_three_node,
                                               variable_name);
 
 
@@ -1085,7 +1085,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
           /* Add the __mf_register call at the current appending point.  */
           if (gsi_end_p (initially_stmts))
            {
-             if (!DECL_ARTIFICIAL (decl))
+             if (!mf_artificial (decl))
                warning (OPT_Wmudflap,
                         "mudflap cannot track %qE in stub function",
                         DECL_NAME (decl));
@@ -1101,7 +1101,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
           mf_mark (decl);
         }
 
-      decl = TREE_CHAIN (decl);
+      decl = DECL_CHAIN (decl);
     }
 
   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
@@ -1233,13 +1233,13 @@ mudflap_register_call (tree obj, tree object_size, tree varname)
   tree arg, call_stmt;
 
   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
-  arg = convert (ptr_type_node, arg);
+  arg = fold_convert (ptr_type_node, arg);
 
   call_stmt = build_call_expr (mf_register_fndecl, 4,
                               arg,
-                              convert (size_type_node, object_size),
+                              fold_convert (size_type_node, object_size),
                               /* __MF_TYPE_STATIC */
-                              build_int_cst (NULL_TREE, 4),
+                              build_int_cst (integer_type_node, 4),
                               varname);
 
   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
@@ -1256,7 +1256,7 @@ mudflap_enqueue_decl (tree obj)
      during mudflap_finish_file ().  That would confuse the user,
      since the text would refer to variables that don't show up in the
      user's source code.  */
-  if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
+  if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj))
     return;
 
   VEC_safe_push (tree, gc, deferred_static_decls, obj);
@@ -1272,7 +1272,7 @@ mudflap_enqueue_constant (tree obj)
     return;
 
   if (TREE_CODE (obj) == STRING_CST)
-    object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
+    object_size = size_int (TREE_STRING_LENGTH (obj));
   else
     object_size = size_in_bytes (TREE_TYPE (obj));
 
@@ -1292,7 +1292,7 @@ mudflap_finish_file (void)
   tree ctor_statements = NULL_TREE;
 
   /* No need to continue when there were errors.  */
-  if (errorcount != 0 || sorrycount != 0)
+  if (seen_error ())
     return;
 
   /* Insert a call to __mf_init.  */
@@ -1314,7 +1314,7 @@ mudflap_finish_file (void)
     {
       size_t i;
       tree obj;
-      for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
+      FOR_EACH_VEC_ELT (tree, deferred_static_decls, i, obj)
         {
           gcc_assert (DECL_P (obj));
 
@@ -1377,7 +1377,7 @@ struct gimple_opt_pass pass_mudflap_1 =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_dump_func                        /* todo_flags_finish */
+  0                                     /* todo_flags_finish */
  }
 };
 
@@ -1397,7 +1397,7 @@ struct gimple_opt_pass pass_mudflap_2 =
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   TODO_verify_flow | TODO_verify_stmts
-  | TODO_dump_func | TODO_update_ssa    /* todo_flags_finish */
+  | TODO_update_ssa                     /* todo_flags_finish */
  }
 };