]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree-mudflap.c
tree-ssa.h: Remove all #include's
[thirdparty/gcc.git] / gcc / tree-mudflap.c
index e4f6ec0b3319c94599400e20f0df673409c353df..a1503118af8408a0cb941bed174d18105ab30e94 100644 (file)
@@ -1,6 +1,5 @@
 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 2002-2013 Free Software Foundation, Inc.
    Contributed by Frank Ch. Eigler <fche@redhat.com>
    and Graydon Hoare <graydon@redhat.com>
 
@@ -33,17 +32,18 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-inline.h"
 #include "gimple.h"
 #include "tree-iterator.h"
-#include "tree-flow.h"
+#include "cgraph.h"
+#include "tree-cfg.h"
 #include "tree-mudflap.h"
-#include "tree-dump.h"
 #include "tree-pass.h"
 #include "hashtab.h"
 #include "diagnostic.h"
 #include "demangle.h"
 #include "langhooks.h"
 #include "ggc.h"
-#include "cgraph.h"
-#include "gimple.h"
+#include "tree-ssa-address.h"
+
+extern void add_bb_to_loop (basic_block, struct loop *);
 
 /* Internal function decls */
 
@@ -106,20 +106,12 @@ mf_build_string (const char *string)
 static tree
 mf_varname_tree (tree decl)
 {
-  static pretty_printer buf_rec;
-  static int initialized = 0;
-  pretty_printer *buf = & buf_rec;
   const char *buf_contents;
   tree result;
 
   gcc_assert (decl);
 
-  if (!initialized)
-    {
-      pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
-      initialized = 1;
-    }
-  pp_clear_output_area (buf);
+  pretty_printer buf;
 
   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
   {
@@ -134,17 +126,17 @@ mf_varname_tree (tree decl)
     if (sourcefile == NULL)
       sourcefile = "<unknown file>";
 
-    pp_string (buf, sourcefile);
+    pp_string (&buf, sourcefile);
 
     if (sourceline != 0)
       {
-        pp_string (buf, ":");
-        pp_decimal_int (buf, sourceline);
+        pp_colon (&buf);
+        pp_decimal_int (&buf, sourceline);
 
         if (sourcecolumn != 0)
           {
-            pp_string (buf, ":");
-            pp_decimal_int (buf, sourcecolumn);
+            pp_colon (&buf);
+            pp_decimal_int (&buf, sourcecolumn);
           }
       }
   }
@@ -152,7 +144,7 @@ mf_varname_tree (tree decl)
   if (current_function_decl != NULL_TREE)
     {
       /* Add (FUNCTION) */
-      pp_string (buf, " (");
+      pp_string (&buf, " (");
       {
         const char *funcname = NULL;
         if (DECL_NAME (current_function_decl))
@@ -160,12 +152,12 @@ mf_varname_tree (tree decl)
         if (funcname == NULL)
           funcname = "anonymous fn";
 
-        pp_string (buf, funcname);
+        pp_string (&buf, funcname);
       }
-      pp_string (buf, ") ");
+      pp_string (&buf, ") ");
     }
   else
-    pp_string (buf, " ");
+    pp_space (&buf);
 
   /* Add <variable-declaration>, possibly demangled.  */
   {
@@ -186,13 +178,13 @@ mf_varname_tree (tree decl)
     if (declname == NULL)
       declname = "<unnamed variable>";
 
-    pp_string (buf, declname);
+    pp_string (&buf, declname);
   }
 
   /* Return the lot as a new STRING_CST.  */
-  buf_contents = pp_base_formatted_text (buf);
+  buf_contents = ggc_strdup (pp_formatted_text (&buf));
   result = mf_build_string (buf_contents);
-  pp_clear_output_area (buf);
+  pp_clear_output_area (&buf);
 
   return result;
 }
@@ -425,10 +417,6 @@ execute_mudflap_function_ops (void)
 
   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 ();
@@ -470,15 +458,15 @@ static void
 mf_decl_cache_locals (void)
 {
   gimple g;
-  gimple_seq seq = gimple_seq_alloc ();
+  gimple_seq seq = NULL;
 
   /* Build the cache vars.  */
   mf_cache_shift_decl_l
-    = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_shift_decl),
+    = mf_mark (create_tmp_reg (TREE_TYPE (mf_cache_shift_decl),
                                "__mf_lookup_shift_l"));
 
   mf_cache_mask_decl_l
-    = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_mask_decl),
+    = mf_mark (create_tmp_reg (TREE_TYPE (mf_cache_mask_decl),
                                "__mf_lookup_mask_l"));
 
   /* Build initialization nodes for the cache vars.  We just load the
@@ -560,13 +548,17 @@ mf_build_check_statement_for (tree base, tree limit,
       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
     }
 
+  /* Update loop info.  */
+  if (current_loops)
+    add_bb_to_loop (then_bb, cond_bb->loop_father);
+
   /* Build our local variables.  */
-  mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem");
-  mf_base = make_rename_temp (mf_uintptr_type, "__mf_base");
-  mf_limit = make_rename_temp (mf_uintptr_type, "__mf_limit");
+  mf_elem = create_tmp_reg (mf_cache_structptr_type, "__mf_elem");
+  mf_base = create_tmp_reg (mf_uintptr_type, "__mf_base");
+  mf_limit = create_tmp_reg (mf_uintptr_type, "__mf_limit");
 
   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
-  seq = gimple_seq_alloc ();
+  seq = NULL;
   t = fold_convert_loc (location, mf_uintptr_type,
                        unshare_expr (base));
   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
@@ -644,7 +636,7 @@ mf_build_check_statement_for (tree base, tree limit,
   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
   gimple_seq_add_seq (&seq, stmts);
-  cond = make_rename_temp (boolean_type_node, "__mf_unlikely_cond");
+  cond = create_tmp_reg (boolean_type_node, "__mf_unlikely_cond");
   g = gimple_build_assign  (cond, t);
   gimple_set_location (g, location);
   gimple_seq_add_stmt (&seq, g);
@@ -677,7 +669,7 @@ mf_build_check_statement_for (tree base, tree limit,
 
      This is the body of the conditional.  */
 
-  seq = gimple_seq_alloc ();
+  seq = NULL;
   /* u is a string, so it is already a gimple value.  */
   u = mf_file_function_line_tree (location);
   /* NB: we pass the overall [base..limit] range to mf_check.  */
@@ -698,7 +690,7 @@ mf_build_check_statement_for (tree base, tree limit,
          gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
          e = split_block (then_bb, g);
          then_bb = e->dest;
-         seq = gimple_seq_alloc ();
+         seq = NULL;
        }
 
       g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
@@ -876,6 +868,9 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
       break;
 
     case MEM_REF:
+      if (addr_expr_of_non_mem_decl_p (TREE_OPERAND (t, 0)))
+       return;
+
       addr = fold_build_pointer_plus_loc (location, TREE_OPERAND (t, 0),
                                          TREE_OPERAND (t, 1));
       base = addr;
@@ -885,6 +880,9 @@ mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
       break;
 
     case TARGET_MEM_REF:
+      if (addr_expr_of_non_mem_decl_p (TMR_BASE (t)))
+       return;
+
       addr = tree_mem_ref_addr (ptr_type_node, t);
       base = addr;
       limit = fold_build_pointer_plus_hwi_loc (location,
@@ -1108,7 +1106,7 @@ mx_register_decls (tree decl, gimple_seq seq, location_t location)
   if (finally_stmts != NULL)
     {
       gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
-      gimple_seq new_seq = gimple_seq_alloc ();
+      gimple_seq new_seq = NULL;
 
       gimple_seq_add_stmt (&new_seq, stmt);
       return new_seq;
@@ -1222,7 +1220,7 @@ mf_marked_p (tree t)
    delayed until program finish time.  If they're still incomplete by
    then, warnings are emitted.  */
 
-static GTY (()) VEC(tree,gc) *deferred_static_decls;
+static GTY (()) vec<tree, va_gc> *deferred_static_decls;
 
 /* A list of statements for calling __mf_register() at startup time.  */
 static GTY (()) tree enqueued_call_stmt_chain;
@@ -1259,7 +1257,7 @@ mudflap_enqueue_decl (tree obj)
   if (DECL_P (obj) && DECL_EXTERNAL (obj) && mf_artificial (obj))
     return;
 
-  VEC_safe_push (tree, gc, deferred_static_decls, obj);
+  vec_safe_push (deferred_static_decls, obj);
 }
 
 
@@ -1314,7 +1312,7 @@ mudflap_finish_file (void)
     {
       size_t i;
       tree obj;
-      FOR_EACH_VEC_ELT (tree, deferred_static_decls, i, obj)
+      FOR_EACH_VEC_ELT (*deferred_static_decls, i, obj)
         {
           gcc_assert (DECL_P (obj));
 
@@ -1328,6 +1326,16 @@ mudflap_finish_file (void)
           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
             continue;
 
+         /* If we're neither emitting nor referencing the symbol,
+            don't register it.  We have to register external symbols
+            if they happen to be in other files not compiled with
+            mudflap (say system libraries), and we must not register
+            internal symbols that we don't emit or they'll become
+            dangling references or force symbols to be emitted that
+            didn't have to.  */
+         if (!symtab_get_node (obj))
+           continue;
+
           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
             {
               warning (OPT_Wmudflap,
@@ -1341,7 +1349,7 @@ mudflap_finish_file (void)
                                  mf_varname_tree (obj));
         }
 
-      VEC_truncate (tree, deferred_static_decls, 0);
+      deferred_static_decls->truncate (0);
     }
 
   /* Append all the enqueued registration calls.  */
@@ -1362,43 +1370,81 @@ gate_mudflap (void)
   return flag_mudflap != 0;
 }
 
-struct gimple_opt_pass pass_mudflap_1 =
+namespace {
+
+const pass_data pass_data_mudflap_1 =
 {
- {
-  GIMPLE_PASS,
-  "mudflap1",                           /* name */
-  gate_mudflap,                         /* gate */
-  execute_mudflap_function_decls,       /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_NONE,                              /* tv_id */
-  PROP_gimple_any,                      /* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  0                                     /* todo_flags_finish */
- }
+  GIMPLE_PASS, /* type */
+  "mudflap1", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  true, /* has_gate */
+  true, /* has_execute */
+  TV_NONE, /* tv_id */
+  PROP_gimple_any, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
 };
 
-struct gimple_opt_pass pass_mudflap_2 =
+class pass_mudflap_1 : public gimple_opt_pass
 {
- {
-  GIMPLE_PASS,
-  "mudflap2",                           /* name */
-  gate_mudflap,                         /* gate */
-  execute_mudflap_function_ops,         /* execute */
-  NULL,                                 /* sub */
-  NULL,                                 /* next */
-  0,                                    /* static_pass_number */
-  TV_NONE,                              /* tv_id */
-  PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */
-  0,                                    /* properties_provided */
-  0,                                    /* properties_destroyed */
-  0,                                    /* todo_flags_start */
-  TODO_verify_flow | TODO_verify_stmts
-  | TODO_update_ssa                     /* todo_flags_finish */
- }
+public:
+  pass_mudflap_1 (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_mudflap_1, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate () { return gate_mudflap (); }
+  unsigned int execute () { return execute_mudflap_function_decls (); }
+
+}; // class pass_mudflap_1
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_1 (gcc::context *ctxt)
+{
+  return new pass_mudflap_1 (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_mudflap_2 =
+{
+  GIMPLE_PASS, /* type */
+  "mudflap2", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  true, /* has_gate */
+  true, /* has_execute */
+  TV_NONE, /* tv_id */
+  ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  ( TODO_verify_flow | TODO_verify_stmts
+    | TODO_update_ssa ), /* todo_flags_finish */
 };
 
+class pass_mudflap_2 : public gimple_opt_pass
+{
+public:
+  pass_mudflap_2 (gcc::context *ctxt)
+    : gimple_opt_pass (pass_data_mudflap_2, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate () { return gate_mudflap (); }
+  unsigned int execute () { return execute_mudflap_function_ops (); }
+
+}; // class pass_mudflap_2
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_2 (gcc::context *ctxt)
+{
+  return new pass_mudflap_2 (ctxt);
+}
+
 #include "gt-tree-mudflap.h"