OSDN Git Service

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