OSDN Git Service

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