OSDN Git Service

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