OSDN Git Service

3f77b2cb1f69a2276b03554a4e3b1b74c02a7102
[pf3gnuchains/gcc-fork.git] / gcc / tree-mudflap.c
1 /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3    Free Software Foundation, Inc.
4    Contributed by Frank Ch. Eigler <fche@redhat.com>
5    and Graydon Hoare <graydon@redhat.com>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "hard-reg-set.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "basic-block.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "tree-inline.h"
36 #include "gimple.h"
37 #include "tree-iterator.h"
38 #include "tree-flow.h"
39 #include "tree-mudflap.h"
40 #include "tree-dump.h"
41 #include "tree-pass.h"
42 #include "hashtab.h"
43 #include "diagnostic.h"
44 #include <demangle.h>
45 #include "langhooks.h"
46 #include "ggc.h"
47 #include "cgraph.h"
48 #include "toplev.h"
49 #include "gimple.h"
50
51 /* Internal function decls */
52
53
54 /* Options.  */
55 #define flag_mudflap_threads (flag_mudflap == 2)
56
57 /* Helpers.  */
58 static tree mf_build_string (const char *string);
59 static tree mf_varname_tree (tree);
60 static tree mf_file_function_line_tree (location_t);
61
62 /* Indirection-related instrumentation.  */
63 static void mf_decl_cache_locals (void);
64 static void mf_decl_clear_locals (void);
65 static void mf_xform_derefs (void);
66 static unsigned int execute_mudflap_function_ops (void);
67
68 /* Addressable variables instrumentation.  */
69 static void mf_xform_decls (gimple_seq, tree);
70 static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *,
71                                 struct walk_stmt_info *);
72 static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
73 static unsigned int execute_mudflap_function_decls (void);
74
75
76 /* ------------------------------------------------------------------------ */
77 /* Some generally helpful functions for mudflap instrumentation.  */
78
79 /* Build a reference to a literal string.  */
80 static tree
81 mf_build_string (const char *string)
82 {
83   size_t len = strlen (string);
84   tree result = mf_mark (build_string (len + 1, string));
85
86   TREE_TYPE (result) = build_array_type
87     (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
88   TREE_CONSTANT (result) = 1;
89   TREE_READONLY (result) = 1;
90   TREE_STATIC (result) = 1;
91
92   result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);
93
94   return mf_mark (result);
95 }
96
97 /* Create a properly typed STRING_CST node that describes the given
98    declaration.  It will be used as an argument for __mf_register().
99    Try to construct a helpful string, including file/function/variable
100    name.  */
101
102 static tree
103 mf_varname_tree (tree decl)
104 {
105   static pretty_printer buf_rec;
106   static int initialized = 0;
107   pretty_printer *buf = & buf_rec;
108   const char *buf_contents;
109   tree result;
110
111   gcc_assert (decl);
112
113   if (!initialized)
114     {
115       pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
116       initialized = 1;
117     }
118   pp_clear_output_area (buf);
119
120   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
121   {
122     expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl));
123     const char *sourcefile;
124     unsigned sourceline = xloc.line;
125     unsigned sourcecolumn = 0;
126     sourcecolumn = xloc.column;
127     sourcefile = xloc.file;
128     if (sourcefile == NULL && current_function_decl != NULL_TREE)
129       sourcefile = DECL_SOURCE_FILE (current_function_decl);
130     if (sourcefile == NULL)
131       sourcefile = "<unknown file>";
132
133     pp_string (buf, sourcefile);
134
135     if (sourceline != 0)
136       {
137         pp_string (buf, ":");
138         pp_decimal_int (buf, sourceline);
139
140         if (sourcecolumn != 0)
141           {
142             pp_string (buf, ":");
143             pp_decimal_int (buf, sourcecolumn);
144           }
145       }
146   }
147
148   if (current_function_decl != NULL_TREE)
149     {
150       /* Add (FUNCTION) */
151       pp_string (buf, " (");
152       {
153         const char *funcname = NULL;
154         if (DECL_NAME (current_function_decl))
155           funcname = lang_hooks.decl_printable_name (current_function_decl, 1);
156         if (funcname == NULL)
157           funcname = "anonymous fn";
158
159         pp_string (buf, funcname);
160       }
161       pp_string (buf, ") ");
162     }
163   else
164     pp_string (buf, " ");
165
166   /* Add <variable-declaration>, possibly demangled.  */
167   {
168     const char *declname = NULL;
169
170     if (DECL_NAME (decl) != NULL)
171       {
172         if (strcmp ("GNU C++", lang_hooks.name) == 0)
173           {
174             /* The gcc/cp decl_printable_name hook doesn't do as good a job as
175                the libiberty demangler.  */
176             declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)),
177                                        DMGL_AUTO | DMGL_VERBOSE);
178           }
179         if (declname == NULL)
180           declname = lang_hooks.decl_printable_name (decl, 3);
181       }
182     if (declname == NULL)
183       declname = "<unnamed variable>";
184
185     pp_string (buf, declname);
186   }
187
188   /* Return the lot as a new STRING_CST.  */
189   buf_contents = pp_base_formatted_text (buf);
190   result = mf_build_string (buf_contents);
191   pp_clear_output_area (buf);
192
193   return result;
194 }
195
196
197 /* And another friend, for producing a simpler message.  */
198
199 static tree
200 mf_file_function_line_tree (location_t location)
201 {
202   expanded_location xloc = expand_location (location);
203   const char *file = NULL, *colon, *line, *op, *name, *cp;
204   char linecolbuf[30]; /* Enough for two decimal numbers plus a colon.  */
205   char *string;
206   tree result;
207
208   /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]].  */
209   file = xloc.file;
210   if (file == NULL && current_function_decl != NULL_TREE)
211     file = DECL_SOURCE_FILE (current_function_decl);
212   if (file == NULL)
213     file = "<unknown file>";
214
215   if (xloc.line > 0)
216     {
217       if (xloc.column > 0)
218         sprintf (linecolbuf, "%d:%d", xloc.line, xloc.column);
219       else
220         sprintf (linecolbuf, "%d", xloc.line);
221       colon = ":";
222       line = linecolbuf;
223     }
224   else
225     colon = line = "";
226
227   /* Add (FUNCTION).  */
228   name = lang_hooks.decl_printable_name (current_function_decl, 1);
229   if (name)
230     {
231       op = " (";
232       cp = ")";
233     }
234   else
235     op = name = cp = "";
236
237   string = concat (file, colon, line, op, name, cp, NULL);
238   result = mf_build_string (string);
239   free (string);
240
241   return result;
242 }
243
244
245 /* global tree nodes */
246
247 /* Global tree objects for global variables and functions exported by
248    mudflap runtime library.  mf_init_extern_trees must be called
249    before using these.  */
250
251 /* uintptr_t (usually "unsigned long") */
252 static GTY (()) tree mf_uintptr_type;
253
254 /* struct __mf_cache { uintptr_t low; uintptr_t high; }; */
255 static GTY (()) tree mf_cache_struct_type;
256
257 /* struct __mf_cache * const */
258 static GTY (()) tree mf_cache_structptr_type;
259
260 /* extern struct __mf_cache __mf_lookup_cache []; */
261 static GTY (()) tree mf_cache_array_decl;
262
263 /* extern unsigned char __mf_lc_shift; */
264 static GTY (()) tree mf_cache_shift_decl;
265
266 /* extern uintptr_t __mf_lc_mask; */
267 static GTY (()) tree mf_cache_mask_decl;
268
269 /* Their function-scope local shadows, used in single-threaded mode only.  */
270
271 /* auto const unsigned char __mf_lc_shift_l; */
272 static GTY (()) tree mf_cache_shift_decl_l;
273
274 /* auto const uintptr_t __mf_lc_mask_l; */
275 static GTY (()) tree mf_cache_mask_decl_l;
276
277 /* extern void __mf_check (void *ptr, size_t sz, int type, const char *); */
278 static GTY (()) tree mf_check_fndecl;
279
280 /* extern void __mf_register (void *ptr, size_t sz, int type, const char *); */
281 static GTY (()) tree mf_register_fndecl;
282
283 /* extern void __mf_unregister (void *ptr, size_t sz, int type); */
284 static GTY (()) tree mf_unregister_fndecl;
285
286 /* extern void __mf_init (); */
287 static GTY (()) tree mf_init_fndecl;
288
289 /* extern int __mf_set_options (const char*); */
290 static GTY (()) tree mf_set_options_fndecl;
291
292
293 /* Helper for mudflap_init: construct a decl with the given category,
294    name, and type, mark it an external reference, and pushdecl it.  */
295 static inline tree
296 mf_make_builtin (enum tree_code category, const char *name, tree type)
297 {
298   tree decl = mf_mark (build_decl (category, get_identifier (name), type));
299   TREE_PUBLIC (decl) = 1;
300   DECL_EXTERNAL (decl) = 1;
301   lang_hooks.decls.pushdecl (decl);
302   /* The decl was declared by the compiler.  */
303   DECL_ARTIFICIAL (decl) = 1;
304   /* And we don't want debug info for it.  */
305   DECL_IGNORED_P (decl) = 1;
306   return decl;
307 }
308
309 /* Helper for mudflap_init: construct a tree corresponding to the type
310      struct __mf_cache { uintptr_t low; uintptr_t high; };
311      where uintptr_t is the FIELD_TYPE argument.  */
312 static inline tree
313 mf_make_mf_cache_struct_type (tree field_type)
314 {
315   /* There is, abominably, no language-independent way to construct a
316      RECORD_TYPE.  So we have to call the basic type construction
317      primitives by hand.  */
318   tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
319   tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);
320
321   tree struct_type = make_node (RECORD_TYPE);
322   DECL_CONTEXT (fieldlo) = struct_type;
323   DECL_CONTEXT (fieldhi) = struct_type;
324   TREE_CHAIN (fieldlo) = fieldhi;
325   TYPE_FIELDS (struct_type) = fieldlo;
326   TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
327   layout_type (struct_type);
328
329   return struct_type;
330 }
331
332 #define build_function_type_0(rtype)                                    \
333   build_function_type (rtype, void_list_node)
334 #define build_function_type_1(rtype, arg1)                              \
335   build_function_type (rtype, tree_cons (0, arg1, void_list_node))
336 #define build_function_type_3(rtype, arg1, arg2, arg3)                  \
337   build_function_type (rtype,                                           \
338                        tree_cons (0, arg1,                              \
339                                   tree_cons (0, arg2,                   \
340                                               tree_cons (0, arg3,       \
341                                                          void_list_node))))
342 #define build_function_type_4(rtype, arg1, arg2, arg3, arg4)            \
343   build_function_type (rtype,                                           \
344                        tree_cons (0, arg1,                              \
345                                   tree_cons (0, arg2,                   \
346                                              tree_cons (0, arg3,        \
347                                                         tree_cons (0, arg4, \
348                                                                    void_list_node)))))
349
350 /* Initialize the global tree nodes that correspond to mf-runtime.h
351    declarations.  */
352 void
353 mudflap_init (void)
354 {
355   static bool done = false;
356   tree mf_const_string_type;
357   tree mf_cache_array_type;
358   tree mf_check_register_fntype;
359   tree mf_unregister_fntype;
360   tree mf_init_fntype;
361   tree mf_set_options_fntype;
362
363   if (done)
364     return;
365   done = true;
366
367   mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode,
368                                                     /*unsignedp=*/true);
369   mf_const_string_type
370     = build_pointer_type (build_qualified_type
371                           (char_type_node, TYPE_QUAL_CONST));
372
373   mf_cache_struct_type = mf_make_mf_cache_struct_type (mf_uintptr_type);
374   mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
375   mf_cache_array_type = build_array_type (mf_cache_struct_type, 0);
376   mf_check_register_fntype =
377     build_function_type_4 (void_type_node, ptr_type_node, size_type_node,
378                            integer_type_node, mf_const_string_type);
379   mf_unregister_fntype =
380     build_function_type_3 (void_type_node, ptr_type_node, size_type_node,
381                            integer_type_node);
382   mf_init_fntype =
383     build_function_type_0 (void_type_node);
384   mf_set_options_fntype =
385     build_function_type_1 (integer_type_node, mf_const_string_type);
386
387   mf_cache_array_decl = mf_make_builtin (VAR_DECL, "__mf_lookup_cache",
388                                          mf_cache_array_type);
389   mf_cache_shift_decl = mf_make_builtin (VAR_DECL, "__mf_lc_shift",
390                                          unsigned_char_type_node);
391   mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask",
392                                         mf_uintptr_type);
393   /* Don't process these in mudflap_enqueue_decl, should they come by
394      there for some reason.  */
395   mf_mark (mf_cache_array_decl);
396   mf_mark (mf_cache_shift_decl);
397   mf_mark (mf_cache_mask_decl);
398   mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check",
399                                      mf_check_register_fntype);
400   mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register",
401                                         mf_check_register_fntype);
402   mf_unregister_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_unregister",
403                                           mf_unregister_fntype);
404   mf_init_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_init",
405                                     mf_init_fntype);
406   mf_set_options_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_set_options",
407                                            mf_set_options_fntype);
408 }
409 #undef build_function_type_4
410 #undef build_function_type_3
411 #undef build_function_type_1
412 #undef build_function_type_0
413
414
415 /* ------------------------------------------------------------------------ */
416 /* Memory reference transforms. Perform the mudflap indirection-related
417    tree transforms on the current function.
418
419    This is the second part of the mudflap instrumentation.  It works on
420    low-level GIMPLE using the CFG, because we want to run this pass after
421    tree optimizations have been performed, but we have to preserve the CFG
422    for expansion from trees to RTL.  */
423
424 static unsigned int
425 execute_mudflap_function_ops (void)
426 {
427   struct gimplify_ctx gctx;
428
429   /* Don't instrument functions such as the synthetic constructor
430      built during mudflap_finish_file.  */
431   if (mf_marked_p (current_function_decl) ||
432       DECL_ARTIFICIAL (current_function_decl))
433     return 0;
434
435   push_gimplify_context (&gctx);
436
437   /* In multithreaded mode, don't cache the lookup cache parameters.  */
438   if (! flag_mudflap_threads)
439     mf_decl_cache_locals ();
440
441   mf_xform_derefs ();
442
443   if (! flag_mudflap_threads)
444     mf_decl_clear_locals ();
445
446   pop_gimplify_context (NULL);
447   return 0;
448 }
449
450 /* Create and initialize local shadow variables for the lookup cache
451    globals.  Put their decls in the *_l globals for use by
452    mf_build_check_statement_for.  */
453
454 static void
455 mf_decl_cache_locals (void)
456 {
457   gimple g;
458   gimple_seq seq = gimple_seq_alloc ();
459
460   /* Build the cache vars.  */
461   mf_cache_shift_decl_l
462     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl),
463                                "__mf_lookup_shift_l"));
464
465   mf_cache_mask_decl_l
466     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl),
467                                "__mf_lookup_mask_l"));
468
469   /* Build initialization nodes for the cache vars.  We just load the
470      globals into the cache variables.  */
471   g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
472   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
473   gimple_seq_add_stmt (&seq, g);
474
475   g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
476   gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
477   gimple_seq_add_stmt (&seq, g);
478
479   insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
480
481   gsi_commit_edge_inserts ();
482 }
483
484
485 static void
486 mf_decl_clear_locals (void)
487 {
488   /* Unset local shadows.  */
489   mf_cache_shift_decl_l = NULL_TREE;
490   mf_cache_mask_decl_l = NULL_TREE;
491 }
492
493 static void
494 mf_build_check_statement_for (tree base, tree limit,
495                               gimple_stmt_iterator *instr_gsi,
496                               location_t location, tree dirflag)
497 {
498   gimple_stmt_iterator gsi;
499   basic_block cond_bb, then_bb, join_bb;
500   edge e;
501   tree cond, t, u, v;
502   tree mf_base;
503   tree mf_elem;
504   tree mf_limit;
505   gimple g;
506   gimple_seq seq;
507
508   /* We first need to split the current basic block, and start altering
509      the CFG.  This allows us to insert the statements we're about to
510      construct into the right basic blocks.  */
511
512   cond_bb = gimple_bb (gsi_stmt (*instr_gsi));
513   gsi = *instr_gsi;
514   gsi_prev (&gsi);
515   if (! gsi_end_p (gsi))
516     e = split_block (cond_bb, gsi_stmt (gsi));
517   else
518     e = split_block_after_labels (cond_bb);
519   cond_bb = e->src;
520   join_bb = e->dest;
521
522   /* A recap at this point: join_bb is the basic block at whose head
523      is the gimple statement for which this check expression is being
524      built.  cond_bb is the (possibly new, synthetic) basic block the
525      end of which will contain the cache-lookup code, and a
526      conditional that jumps to the cache-miss code or, much more
527      likely, over to join_bb.  */
528
529   /* Create the bb that contains the cache-miss fallback block (mf_check).  */
530   then_bb = create_empty_bb (cond_bb);
531   make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
532   make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU);
533
534   /* Mark the pseudo-fallthrough edge from cond_bb to join_bb.  */
535   e = find_edge (cond_bb, join_bb);
536   e->flags = EDGE_FALSE_VALUE;
537   e->count = cond_bb->count;
538   e->probability = REG_BR_PROB_BASE;
539
540   /* Update dominance info.  Note that bb_join's data was
541      updated by split_block.  */
542   if (dom_info_available_p (CDI_DOMINATORS))
543     {
544       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
545       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
546     }
547
548   /* Build our local variables.  */
549   mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
550   mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
551   mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
552
553   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
554   seq = gimple_seq_alloc ();
555   t = fold_convert (mf_uintptr_type, unshare_expr (base));
556   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
557   g = gimple_build_assign (mf_base, t);
558   gimple_set_location (g, location);
559   gimple_seq_add_stmt (&seq, g);
560
561   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
562   t = fold_convert (mf_uintptr_type, unshare_expr (limit));
563   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
564   g = gimple_build_assign (mf_limit, t);
565   gimple_set_location (g, location);
566   gimple_seq_add_stmt (&seq, g);
567
568   /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
569                                             & __mf_mask].  */
570   t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base,
571               flag_mudflap_threads ? mf_cache_shift_decl
572                : mf_cache_shift_decl_l);
573   t = build2 (BIT_AND_EXPR, mf_uintptr_type, t,
574               flag_mudflap_threads ? mf_cache_mask_decl
575                : mf_cache_mask_decl_l);
576   t = build4 (ARRAY_REF,
577               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
578               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
579   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
580   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
581   g = gimple_build_assign (mf_elem, t);
582   gimple_set_location (g, location);
583   gimple_seq_add_stmt (&seq, g);
584
585   /* Quick validity check.
586
587      if (__mf_elem->low > __mf_base
588          || (__mf_elem_high < __mf_limit))
589         {
590           __mf_check ();
591           ... and only if single-threaded:
592           __mf_lookup_shift_1 = f...;
593           __mf_lookup_mask_l = ...;
594         }
595
596      It is expected that this body of code is rarely executed so we mark
597      the edge to the THEN clause of the conditional jump as unlikely.  */
598
599   /* Construct t <-- '__mf_elem->low  > __mf_base'.  */
600   t = build3 (COMPONENT_REF, mf_uintptr_type,
601               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
602               TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
603   t = build2 (GT_EXPR, boolean_type_node, t, mf_base);
604
605   /* Construct '__mf_elem->high < __mf_limit'.
606
607      First build:
608         1) u <--  '__mf_elem->high'
609         2) v <--  '__mf_limit'.
610
611      Then build 'u <-- (u < v).  */
612
613   u = build3 (COMPONENT_REF, mf_uintptr_type,
614               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
615               TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
616
617   v = mf_limit;
618
619   u = build2 (LT_EXPR, boolean_type_node, u, v);
620
621   /* Build the composed conditional: t <-- 't || u'.  Then store the
622      result of the evaluation of 't' in a temporary variable which we
623      can use as the condition for the conditional jump.  */
624   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
625   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
626   cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
627   g = gimple_build_assign  (cond, t);
628   gimple_set_location (g, location);
629   gimple_seq_add_stmt (&seq, g);
630
631   /* Build the conditional jump.  'cond' is just a temporary so we can
632      simply build a void COND_EXPR.  We do need labels in both arms though.  */
633   g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, NULL_TREE,
634                          NULL_TREE);
635   gimple_set_location (g, location);
636   gimple_seq_add_stmt (&seq, g);
637
638   /* At this point, after so much hard work, we have only constructed
639      the conditional jump,
640
641      if (__mf_elem->low > __mf_base
642          || (__mf_elem_high < __mf_limit))
643
644      The lowered GIMPLE tree representing this code is in the statement
645      list starting at 'head'.
646
647      We can insert this now in the current basic block, i.e. the one that
648      the statement we're instrumenting was originally in.  */
649   gsi = gsi_last_bb (cond_bb);
650   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
651
652   /*  Now build up the body of the cache-miss handling:
653
654      __mf_check();
655      refresh *_l vars.
656
657      This is the body of the conditional.  */
658
659   seq = gimple_seq_alloc ();
660   /* u is a string, so it is already a gimple value.  */
661   u = mf_file_function_line_tree (location);
662   /* NB: we pass the overall [base..limit] range to mf_check.  */
663   v = fold_build2 (PLUS_EXPR, integer_type_node,
664                    fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
665                    integer_one_node);
666   gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
667   g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
668   gimple_seq_add_stmt (&seq, g);
669
670   if (! flag_mudflap_threads)
671     {
672       g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
673       gimple_seq_add_stmt (&seq, g);
674
675       g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
676       gimple_seq_add_stmt (&seq, g);
677     }
678
679   /* Insert the check code in the THEN block.  */
680   gsi = gsi_start_bb (then_bb);
681   gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
682
683   *instr_gsi = gsi_start_bb (join_bb);
684 }
685
686
687 /* Check whether the given decl, generally a VAR_DECL or PARM_DECL, is
688    eligible for instrumentation.  For the mudflap1 pass, this implies
689    that it should be registered with the libmudflap runtime.  For the
690    mudflap2 pass this means instrumenting an indirection operation with
691    respect to the object.
692 */
693 static int
694 mf_decl_eligible_p (tree decl)
695 {
696   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
697           /* The decl must have its address taken.  In the case of
698              arrays, this flag is also set if the indexes are not
699              compile-time known valid constants.  */
700           /* XXX: not sufficient: return-by-value structs! */
701           && TREE_ADDRESSABLE (decl)
702           /* The type of the variable must be complete.  */
703           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
704           /* The decl hasn't been decomposed somehow.  */
705           && !DECL_HAS_VALUE_EXPR_P (decl));
706 }
707
708
709 static void
710 mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
711                    location_t location, tree dirflag)
712 {
713   tree type, base, limit, addr, size, t;
714
715   /* Don't instrument read operations.  */
716   if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
717     return;
718
719   /* Don't instrument marked nodes.  */
720   if (mf_marked_p (*tp))
721     return;
722
723   t = *tp;
724   type = TREE_TYPE (t);
725
726   if (type == error_mark_node)
727     return;
728
729   size = TYPE_SIZE_UNIT (type);
730
731   switch (TREE_CODE (t))
732     {
733     case ARRAY_REF:
734     case COMPONENT_REF:
735       {
736         /* This is trickier than it may first appear.  The reason is
737            that we are looking at expressions from the "inside out" at
738            this point.  We may have a complex nested aggregate/array
739            expression (e.g. "a.b[i].c"), maybe with an indirection as
740            the leftmost operator ("p->a.b.d"), where instrumentation
741            is necessary.  Or we may have an innocent "a.b.c"
742            expression that must not be instrumented.  We need to
743            recurse all the way down the nesting structure to figure it
744            out: looking just at the outer node is not enough.  */          
745         tree var;
746         int component_ref_only = (TREE_CODE (t) == COMPONENT_REF);
747         /* If we have a bitfield component reference, we must note the
748            innermost addressable object in ELT, from which we will
749            construct the byte-addressable bounds of the bitfield.  */
750         tree elt = NULL_TREE;
751         int bitfield_ref_p = (TREE_CODE (t) == COMPONENT_REF
752                               && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)));
753
754         /* Iterate to the top of the ARRAY_REF/COMPONENT_REF
755            containment hierarchy to find the outermost VAR_DECL.  */
756         var = TREE_OPERAND (t, 0);
757         while (1)
758           {
759             if (bitfield_ref_p && elt == NULL_TREE
760                 && (TREE_CODE (var) == ARRAY_REF
761                     || TREE_CODE (var) == COMPONENT_REF))
762               elt = var;
763         
764             if (TREE_CODE (var) == ARRAY_REF)
765               {
766                 component_ref_only = 0;
767                 var = TREE_OPERAND (var, 0);
768               }
769             else if (TREE_CODE (var) == COMPONENT_REF)
770               var = TREE_OPERAND (var, 0);
771             else if (INDIRECT_REF_P (var))
772               {
773                 base = TREE_OPERAND (var, 0);
774                 break;
775               }
776             else 
777               {
778                 gcc_assert (TREE_CODE (var) == VAR_DECL 
779                             || TREE_CODE (var) == PARM_DECL
780                             || TREE_CODE (var) == RESULT_DECL
781                             || TREE_CODE (var) == STRING_CST);
782                 /* Don't instrument this access if the underlying
783                    variable is not "eligible".  This test matches
784                    those arrays that have only known-valid indexes,
785                    and thus are not labeled TREE_ADDRESSABLE.  */
786                 if (! mf_decl_eligible_p (var) || component_ref_only)
787                   return;
788                 else
789                   {
790                     base = build1 (ADDR_EXPR,
791                                    build_pointer_type (TREE_TYPE (var)), var);
792                     break;
793                   }
794               }
795           }
796
797         /* Handle the case of ordinary non-indirection structure
798            accesses.  These have only nested COMPONENT_REF nodes (no
799            INDIRECT_REF), but pass through the above filter loop.
800            Note that it's possible for such a struct variable to match
801            the eligible_p test because someone else might take its
802            address sometime.  */
803
804         /* We need special processing for bitfield components, because
805            their addresses cannot be taken.  */
806         if (bitfield_ref_p)
807           {
808             tree field = TREE_OPERAND (t, 1);
809
810             if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
811               size = DECL_SIZE_UNIT (field);
812             
813             if (elt)
814               elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
815                             elt);
816             addr = fold_convert (ptr_type_node, elt ? elt : base);
817             addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
818                                 addr, fold_convert (sizetype,
819                                                     byte_position (field)));
820           }
821         else
822           addr = build1 (ADDR_EXPR, build_pointer_type (type), t);
823
824         limit = fold_build2 (MINUS_EXPR, mf_uintptr_type,
825                              fold_build2 (PLUS_EXPR, mf_uintptr_type,
826                                           convert (mf_uintptr_type, addr),
827                                           size),
828                              integer_one_node);
829       }
830       break;
831
832     case INDIRECT_REF:
833       addr = TREE_OPERAND (t, 0);
834       base = addr;
835       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
836                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
837                                         size),
838                            size_int (-1));
839       break;
840
841     case TARGET_MEM_REF:
842       addr = tree_mem_ref_addr (ptr_type_node, t);
843       base = addr;
844       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
845                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
846                                         size),
847                            size_int (-1));
848       break;
849
850     case ARRAY_RANGE_REF:
851       warning (OPT_Wmudflap,
852                "mudflap checking not yet implemented for ARRAY_RANGE_REF");
853       return;
854
855     case BIT_FIELD_REF:
856       /* ??? merge with COMPONENT_REF code above? */
857       {
858         tree ofs, rem, bpu;
859
860         /* If we're not dereferencing something, then the access
861            must be ok.  */
862         if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
863           return;
864
865         bpu = bitsize_int (BITS_PER_UNIT);
866         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
867         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
868         ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
869
870         size = convert (bitsizetype, TREE_OPERAND (t, 1));
871         size = size_binop (PLUS_EXPR, size, rem);
872         size = size_binop (CEIL_DIV_EXPR, size, bpu);
873         size = convert (sizetype, size);
874
875         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
876         addr = convert (ptr_type_node, addr);
877         addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
878
879         base = addr;
880         limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
881                              fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
882                                            base, size),
883                              size_int (-1));
884       }
885       break;
886
887     default:
888       return;
889     }
890
891   mf_build_check_statement_for (base, limit, iter, location, dirflag);
892 }
893
894 static void
895 mf_xform_derefs (void)
896 {
897   basic_block bb, next;
898   gimple_stmt_iterator i;
899   int saved_last_basic_block = last_basic_block;
900   enum gimple_rhs_class grhs_class;
901
902   bb = ENTRY_BLOCK_PTR ->next_bb;
903   do
904     {
905       next = bb->next_bb;
906       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
907         {
908           gimple s = gsi_stmt (i);
909
910           /* Only a few GIMPLE statements can reference memory.  */
911           switch (gimple_code (s))
912             {
913             case GIMPLE_ASSIGN:
914               mf_xform_derefs_1 (&i, gimple_assign_lhs_ptr (s),
915                                  gimple_location (s), integer_one_node);
916               mf_xform_derefs_1 (&i, gimple_assign_rhs1_ptr (s),
917                                  gimple_location (s), integer_zero_node);
918               grhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (s));
919               if (grhs_class == GIMPLE_BINARY_RHS)
920                 mf_xform_derefs_1 (&i, gimple_assign_rhs2_ptr (s),
921                                    gimple_location (s), integer_zero_node);
922               break;
923
924             case GIMPLE_RETURN:
925               if (gimple_return_retval (s) != NULL_TREE)
926                 {
927                   mf_xform_derefs_1 (&i, gimple_return_retval_ptr (s),
928                                      gimple_location (s),
929                                      integer_zero_node);
930                 }
931               break;
932
933             default:
934               ;
935             }
936         }
937       bb = next;
938     }
939   while (bb && bb->index <= saved_last_basic_block);
940 }
941
942 /* ------------------------------------------------------------------------ */
943 /* ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
944    transforms on the current function.
945
946    This is the first part of the mudflap instrumentation.  It works on
947    high-level GIMPLE because after lowering, all variables are moved out
948    of their BIND_EXPR binding context, and we lose liveness information
949    for the declarations we wish to instrument.  */
950
951 static unsigned int
952 execute_mudflap_function_decls (void)
953 {
954   struct gimplify_ctx gctx;
955
956   /* Don't instrument functions such as the synthetic constructor
957      built during mudflap_finish_file.  */
958   if (mf_marked_p (current_function_decl) ||
959       DECL_ARTIFICIAL (current_function_decl))
960     return 0;
961
962   push_gimplify_context (&gctx);
963
964   mf_xform_decls (gimple_body (current_function_decl),
965                   DECL_ARGUMENTS (current_function_decl));
966
967   pop_gimplify_context (NULL);
968   return 0;
969 }
970
971 /* This struct is passed between mf_xform_decls to store state needed
972    during the traversal searching for objects that have their
973    addresses taken.  */
974 struct mf_xform_decls_data
975 {
976   tree param_decls;
977 };
978
979
980 /* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
981    _DECLs if appropriate.  Arrange to call the __mf_register function
982    now, and the __mf_unregister function later for each.  Return the
983    gimple sequence after synthesis.  */
984 gimple_seq
985 mx_register_decls (tree decl, gimple_seq seq, location_t location)
986 {
987   gimple_seq finally_stmts = NULL;
988   gimple_stmt_iterator initially_stmts = gsi_start (seq);
989
990   while (decl != NULL_TREE)
991     {
992       if (mf_decl_eligible_p (decl) 
993           /* Not already processed.  */
994           && ! mf_marked_p (decl)
995           /* Automatic variable.  */
996           && ! DECL_EXTERNAL (decl)
997           && ! TREE_STATIC (decl))
998         {
999           tree size = NULL_TREE, variable_name;
1000           gimple unregister_fncall, register_fncall;
1001           tree unregister_fncall_param, register_fncall_param;
1002
1003           /* Variable-sized objects should have sizes already been
1004              gimplified when we got here. */
1005           size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
1006           gcc_assert (is_gimple_val (size));
1007         
1008
1009           unregister_fncall_param =
1010             mf_mark (build1 (ADDR_EXPR,
1011                              build_pointer_type (TREE_TYPE (decl)),
1012                              decl));
1013           /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
1014           unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3,
1015                                                  unregister_fncall_param,
1016                                                  size,
1017                                                  build_int_cst (NULL_TREE, 3));
1018
1019
1020           variable_name = mf_varname_tree (decl);
1021           register_fncall_param =
1022             mf_mark (build1 (ADDR_EXPR,
1023                              build_pointer_type (TREE_TYPE (decl)),
1024                              decl));
1025           /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
1026                             "name") */
1027           register_fncall = gimple_build_call (mf_register_fndecl, 4,
1028                                                register_fncall_param,
1029                                                size,
1030                                                build_int_cst (NULL_TREE, 3),
1031                                                variable_name);
1032           
1033
1034           /* Accumulate the two calls.  */
1035           gimple_set_location (register_fncall, location);
1036           gimple_set_location (unregister_fncall, location);
1037
1038           /* Add the __mf_register call at the current appending point.  */
1039           if (gsi_end_p (initially_stmts))
1040             {
1041               if (!DECL_ARTIFICIAL (decl))
1042                 warning (OPT_Wmudflap,
1043                          "mudflap cannot track %qs in stub function",
1044                          IDENTIFIER_POINTER (DECL_NAME (decl)));
1045             }
1046           else
1047             {
1048               gsi_insert_before (&initially_stmts, register_fncall,
1049                                  GSI_SAME_STMT);
1050
1051               /* Accumulate the FINALLY piece.  */
1052               gimple_seq_add_stmt (&finally_stmts, unregister_fncall);
1053             }
1054           mf_mark (decl);
1055         }
1056
1057       decl = TREE_CHAIN (decl);
1058     }
1059
1060   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
1061   if (finally_stmts != NULL)
1062     {
1063       gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
1064       gimple_seq new_seq = gimple_seq_alloc ();
1065
1066       gimple_seq_add_stmt (&new_seq, stmt);
1067       return new_seq;
1068     }
1069    else
1070     return seq;
1071 }
1072
1073
1074 /* Process every variable mentioned in BIND_EXPRs.  */
1075 static tree
1076 mx_xfn_xform_decls (gimple_stmt_iterator *gsi,
1077                     bool *handled_operands_p ATTRIBUTE_UNUSED,
1078                     struct walk_stmt_info *wi)
1079 {
1080   struct mf_xform_decls_data *d = (struct mf_xform_decls_data *) wi->info;
1081   gimple stmt = gsi_stmt (*gsi);
1082
1083   switch (gimple_code (stmt))
1084     {
1085     case GIMPLE_BIND:
1086       {
1087         /* Process function parameters now (but only once).  */
1088         if (d->param_decls)
1089           {
1090             gimple_bind_set_body (stmt,
1091                                   mx_register_decls (d->param_decls,
1092                                                      gimple_bind_body (stmt),
1093                                                      gimple_location (stmt)));
1094             d->param_decls = NULL_TREE;
1095           }
1096
1097         gimple_bind_set_body (stmt,
1098                               mx_register_decls (gimple_bind_vars (stmt),
1099                                                  gimple_bind_body (stmt),
1100                                                  gimple_location (stmt)));
1101       }
1102       break;
1103
1104     default:
1105       break;
1106     }
1107
1108   return NULL_TREE;
1109 }
1110
1111 /* Perform the object lifetime tracking mudflap transform on the given function
1112    tree.  The tree is mutated in place, with possibly copied subtree nodes.
1113
1114    For every auto variable declared, if its address is ever taken
1115    within the function, then supply its lifetime to the mudflap
1116    runtime with the __mf_register and __mf_unregister calls.
1117 */
1118
1119 static void
1120 mf_xform_decls (gimple_seq fnbody, tree fnparams)
1121 {
1122   struct mf_xform_decls_data d;
1123   struct walk_stmt_info wi;
1124   struct pointer_set_t *pset = pointer_set_create ();
1125
1126   d.param_decls = fnparams;
1127   memset (&wi, 0, sizeof (wi));
1128   wi.info = (void*) &d;
1129   wi.pset = pset;
1130   walk_gimple_seq (fnbody, mx_xfn_xform_decls, NULL, &wi);
1131   pointer_set_destroy (pset);
1132 }
1133
1134
1135 /* ------------------------------------------------------------------------ */
1136 /* Externally visible mudflap functions.  */
1137
1138
1139 /* Mark and return the given tree node to prevent further mudflap
1140    transforms.  */
1141 static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
1142
1143 tree
1144 mf_mark (tree t)
1145 {
1146   void **slot;
1147
1148   if (marked_trees == NULL)
1149     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer,
1150                                     NULL);
1151
1152   slot = htab_find_slot (marked_trees, t, INSERT);
1153   *slot = t;
1154   return t;
1155 }
1156
1157 int
1158 mf_marked_p (tree t)
1159 {
1160   void *entry;
1161
1162   if (marked_trees == NULL)
1163     return 0;
1164
1165   entry = htab_find (marked_trees, t);
1166   return (entry != NULL);
1167 }
1168
1169 /* Remember given node as a static of some kind: global data,
1170    function-scope static, or an anonymous constant.  Its assembler
1171    label is given.  */
1172
1173 /* A list of globals whose incomplete declarations we encountered.
1174    Instead of emitting the __mf_register call for them here, it's
1175    delayed until program finish time.  If they're still incomplete by
1176    then, warnings are emitted.  */
1177
1178 static GTY (()) VEC(tree,gc) *deferred_static_decls;
1179
1180 /* A list of statements for calling __mf_register() at startup time.  */
1181 static GTY (()) tree enqueued_call_stmt_chain;
1182
1183 static void
1184 mudflap_register_call (tree obj, tree object_size, tree varname)
1185 {
1186   tree arg, call_stmt;
1187
1188   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
1189   arg = convert (ptr_type_node, arg);
1190
1191   call_stmt = build_call_expr (mf_register_fndecl, 4,
1192                                arg,
1193                                convert (size_type_node, object_size),
1194                                /* __MF_TYPE_STATIC */
1195                                build_int_cst (NULL_TREE, 4), 
1196                                varname);
1197
1198   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
1199 }
1200
1201 void
1202 mudflap_enqueue_decl (tree obj)
1203 {
1204   if (mf_marked_p (obj))
1205     return;
1206
1207   /* We don't need to process variable decls that are internally
1208      generated extern.  If we did, we'd end up with warnings for them
1209      during mudflap_finish_file ().  That would confuse the user,
1210      since the text would refer to variables that don't show up in the
1211      user's source code.  */
1212   if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
1213     return;
1214
1215   VEC_safe_push (tree, gc, deferred_static_decls, obj);
1216 }
1217
1218
1219 void
1220 mudflap_enqueue_constant (tree obj)
1221 {
1222   tree object_size, varname;
1223
1224   if (mf_marked_p (obj))
1225     return;
1226
1227   if (TREE_CODE (obj) == STRING_CST)
1228     object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
1229   else
1230     object_size = size_in_bytes (TREE_TYPE (obj));
1231
1232   if (TREE_CODE (obj) == STRING_CST)
1233     varname = mf_build_string ("string literal");
1234   else
1235     varname = mf_build_string ("constant");
1236
1237   mudflap_register_call (obj, object_size, varname);
1238 }
1239
1240
1241 /* Emit any file-wide instrumentation.  */
1242 void
1243 mudflap_finish_file (void)
1244 {
1245   tree ctor_statements = NULL_TREE;
1246
1247   /* No need to continue when there were errors.  */
1248   if (errorcount != 0 || sorrycount != 0)
1249     return;
1250
1251   /* Insert a call to __mf_init.  */
1252   {
1253     tree call2_stmt = build_call_expr (mf_init_fndecl, 0);
1254     append_to_statement_list (call2_stmt, &ctor_statements);
1255   }
1256   
1257   /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
1258   if (flag_mudflap_ignore_reads)
1259     {
1260       tree arg = mf_build_string ("-ignore-reads");
1261       tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg);
1262       append_to_statement_list (call_stmt, &ctor_statements);
1263     }
1264
1265   /* Process all enqueued object decls.  */
1266   if (deferred_static_decls)
1267     {
1268       size_t i;
1269       tree obj;
1270       for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
1271         {
1272           gcc_assert (DECL_P (obj));
1273
1274           if (mf_marked_p (obj))
1275             continue;
1276
1277           /* Omit registration for static unaddressed objects.  NB:
1278              Perform registration for non-static objects regardless of
1279              TREE_USED or TREE_ADDRESSABLE, because they may be used
1280              from other compilation units.  */
1281           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
1282             continue;
1283
1284           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
1285             {
1286               warning (OPT_Wmudflap,
1287                        "mudflap cannot track unknown size extern %qs",
1288                        IDENTIFIER_POINTER (DECL_NAME (obj)));
1289               continue;
1290             }
1291           
1292           mudflap_register_call (obj, 
1293                                  size_in_bytes (TREE_TYPE (obj)),
1294                                  mf_varname_tree (obj));
1295         }
1296
1297       VEC_truncate (tree, deferred_static_decls, 0);
1298     }
1299
1300   /* Append all the enqueued registration calls.  */
1301   if (enqueued_call_stmt_chain)
1302     {
1303       append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
1304       enqueued_call_stmt_chain = NULL_TREE;
1305     }
1306
1307   cgraph_build_static_cdtor ('I', ctor_statements, 
1308                              MAX_RESERVED_INIT_PRIORITY-1);
1309 }
1310
1311
1312 static bool
1313 gate_mudflap (void)
1314 {
1315   return flag_mudflap != 0;
1316 }
1317
1318 struct gimple_opt_pass pass_mudflap_1 = 
1319 {
1320  {
1321   GIMPLE_PASS,
1322   "mudflap1",                           /* name */
1323   gate_mudflap,                         /* gate */
1324   execute_mudflap_function_decls,       /* execute */
1325   NULL,                                 /* sub */
1326   NULL,                                 /* next */
1327   0,                                    /* static_pass_number */
1328   0,                                    /* tv_id */
1329   PROP_gimple_any,                      /* properties_required */
1330   0,                                    /* properties_provided */
1331   0,                                    /* properties_destroyed */
1332   0,                                    /* todo_flags_start */
1333   TODO_dump_func                        /* todo_flags_finish */
1334  }
1335 };
1336
1337 struct gimple_opt_pass pass_mudflap_2 = 
1338 {
1339  {
1340   GIMPLE_PASS,
1341   "mudflap2",                           /* name */
1342   gate_mudflap,                         /* gate */
1343   execute_mudflap_function_ops,         /* execute */
1344   NULL,                                 /* sub */
1345   NULL,                                 /* next */
1346   0,                                    /* static_pass_number */
1347   0,                                    /* tv_id */
1348   PROP_gimple_leh,                      /* properties_required */
1349   0,                                    /* properties_provided */
1350   0,                                    /* properties_destroyed */
1351   0,                                    /* todo_flags_start */
1352   TODO_verify_flow | TODO_verify_stmts
1353   | TODO_dump_func                      /* todo_flags_finish */
1354  }
1355 };
1356
1357 #include "gt-tree-mudflap.h"