OSDN Git Service

46650b37dd4f8347ffd4ba072e88e5ff62890593
[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   struct gimplify_ctx gctx;
425
426   /* Don't instrument functions such as the synthetic constructor
427      built during mudflap_finish_file.  */
428   if (mf_marked_p (current_function_decl) ||
429       DECL_ARTIFICIAL (current_function_decl))
430     return 0;
431
432   push_gimplify_context (&gctx);
433
434   /* In multithreaded mode, don't cache the lookup cache parameters.  */
435   if (! flag_mudflap_threads)
436     mf_decl_cache_locals ();
437
438   mf_xform_derefs ();
439
440   if (! flag_mudflap_threads)
441     mf_decl_clear_locals ();
442
443   pop_gimplify_context (NULL);
444   return 0;
445 }
446
447 /* Create and initialize local shadow variables for the lookup cache
448    globals.  Put their decls in the *_l globals for use by
449    mf_build_check_statement_for.  */
450
451 static void
452 mf_decl_cache_locals (void)
453 {
454   tree t, shift_init_stmts, mask_init_stmts;
455   tree_stmt_iterator tsi;
456
457   /* Build the cache vars.  */
458   mf_cache_shift_decl_l
459     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl),
460                                "__mf_lookup_shift_l"));
461
462   mf_cache_mask_decl_l
463     = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl),
464                                "__mf_lookup_mask_l"));
465
466   /* Build initialization nodes for the cache vars.  We just load the
467      globals into the cache variables.  */
468   t = build_gimple_modify_stmt (mf_cache_shift_decl_l, mf_cache_shift_decl);
469   SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
470   gimplify_to_stmt_list (&t);
471   shift_init_stmts = t;
472
473   t = build_gimple_modify_stmt (mf_cache_mask_decl_l, mf_cache_mask_decl);
474   SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
475   gimplify_to_stmt_list (&t);
476   mask_init_stmts = t;
477
478   /* Anticipating multiple entry points, we insert the cache vars
479      initializers in each successor of the ENTRY_BLOCK_PTR.  */
480   for (tsi = tsi_start (shift_init_stmts);
481        ! tsi_end_p (tsi);
482        tsi_next (&tsi))
483     insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
484
485   for (tsi = tsi_start (mask_init_stmts);
486        ! tsi_end_p (tsi);
487        tsi_next (&tsi))
488     insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
489   bsi_commit_edge_inserts ();
490 }
491
492
493 static void
494 mf_decl_clear_locals (void)
495 {
496   /* Unset local shadows.  */
497   mf_cache_shift_decl_l = NULL_TREE;
498   mf_cache_mask_decl_l = NULL_TREE;
499 }
500
501 static void
502 mf_build_check_statement_for (tree base, tree limit,
503                               block_stmt_iterator *instr_bsi,
504                               location_t *locus, tree dirflag)
505 {
506   tree_stmt_iterator head, tsi;
507   block_stmt_iterator bsi;
508   basic_block cond_bb, then_bb, join_bb;
509   edge e;
510   tree cond, t, u, v;
511   tree mf_base;
512   tree mf_elem;
513   tree mf_limit;
514
515   /* We first need to split the current basic block, and start altering
516      the CFG.  This allows us to insert the statements we're about to
517      construct into the right basic blocks.  */
518
519   cond_bb = bb_for_stmt (bsi_stmt (*instr_bsi));
520   bsi = *instr_bsi;
521   bsi_prev (&bsi);
522   if (! bsi_end_p (bsi))
523     e = split_block (cond_bb, bsi_stmt (bsi));
524   else
525     e = split_block_after_labels (cond_bb);
526   cond_bb = e->src;
527   join_bb = e->dest;
528
529   /* A recap at this point: join_bb is the basic block at whose head
530      is the gimple statement for which this check expression is being
531      built.  cond_bb is the (possibly new, synthetic) basic block the
532      end of which will contain the cache-lookup code, and a
533      conditional that jumps to the cache-miss code or, much more
534      likely, over to join_bb.  */
535
536   /* Create the bb that contains the cache-miss fallback block (mf_check).  */
537   then_bb = create_empty_bb (cond_bb);
538   make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
539   make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU);
540
541   /* Mark the pseudo-fallthrough edge from cond_bb to join_bb.  */
542   e = find_edge (cond_bb, join_bb);
543   e->flags = EDGE_FALSE_VALUE;
544   e->count = cond_bb->count;
545   e->probability = REG_BR_PROB_BASE;
546
547   /* Update dominance info.  Note that bb_join's data was
548      updated by split_block.  */
549   if (dom_info_available_p (CDI_DOMINATORS))
550     {
551       set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
552       set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb);
553     }
554
555   /* Build our local variables.  */
556   mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
557   mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
558   mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
559
560   /* Build: __mf_base = (uintptr_t) <base address expression>.  */
561   t = build_gimple_modify_stmt (mf_base,
562                                 fold_convert (mf_uintptr_type,
563                                               unshare_expr (base)));
564   SET_EXPR_LOCUS (t, locus);
565   gimplify_to_stmt_list (&t);
566   head = tsi_start (t);
567   tsi = tsi_last (t);
568
569   /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
570   t = build_gimple_modify_stmt (mf_limit,
571                                 fold_convert (mf_uintptr_type,
572                                               unshare_expr (limit)));
573   SET_EXPR_LOCUS (t, locus);
574   gimplify_to_stmt_list (&t);
575   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
576
577   /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
578                                             & __mf_mask].  */
579   t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base,
580               flag_mudflap_threads ? mf_cache_shift_decl
581                : mf_cache_shift_decl_l);
582   t = build2 (BIT_AND_EXPR, mf_uintptr_type, t,
583               flag_mudflap_threads ? mf_cache_mask_decl
584                : mf_cache_mask_decl_l);
585   t = build4 (ARRAY_REF,
586               TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
587               mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
588   t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
589   t = build_gimple_modify_stmt (mf_elem, t);
590   SET_EXPR_LOCUS (t, locus);
591   gimplify_to_stmt_list (&t);
592   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
593
594   /* Quick validity check.
595
596      if (__mf_elem->low > __mf_base
597          || (__mf_elem_high < __mf_limit))
598         {
599           __mf_check ();
600           ... and only if single-threaded:
601           __mf_lookup_shift_1 = f...;
602           __mf_lookup_mask_l = ...;
603         }
604
605      It is expected that this body of code is rarely executed so we mark
606      the edge to the THEN clause of the conditional jump as unlikely.  */
607
608   /* Construct t <-- '__mf_elem->low  > __mf_base'.  */
609   t = build3 (COMPONENT_REF, mf_uintptr_type,
610               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
611               TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
612   t = build2 (GT_EXPR, boolean_type_node, t, mf_base);
613
614   /* Construct '__mf_elem->high < __mf_limit'.
615
616      First build:
617         1) u <--  '__mf_elem->high'
618         2) v <--  '__mf_limit'.
619
620      Then build 'u <-- (u < v).  */
621
622   u = build3 (COMPONENT_REF, mf_uintptr_type,
623               build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
624               TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
625
626   v = mf_limit;
627
628   u = build2 (LT_EXPR, boolean_type_node, u, v);
629
630   /* Build the composed conditional: t <-- 't || u'.  Then store the
631      result of the evaluation of 't' in a temporary variable which we
632      can use as the condition for the conditional jump.  */
633   t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
634   cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
635   t = build_gimple_modify_stmt (cond, t);
636   gimplify_to_stmt_list (&t);
637   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
638
639   /* Build the conditional jump.  'cond' is just a temporary so we can
640      simply build a void COND_EXPR.  We do need labels in both arms though.  */
641   t = build3 (COND_EXPR, void_type_node, cond, NULL_TREE, NULL_TREE);
642   SET_EXPR_LOCUS (t, locus);
643   tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
644
645   /* At this point, after so much hard work, we have only constructed
646      the conditional jump,
647
648      if (__mf_elem->low > __mf_base
649          || (__mf_elem_high < __mf_limit))
650
651      The lowered GIMPLE tree representing this code is in the statement
652      list starting at 'head'.
653
654      We can insert this now in the current basic block, i.e. the one that
655      the statement we're instrumenting was originally in.  */
656   bsi = bsi_last (cond_bb);
657   for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
658     bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
659
660   /*  Now build up the body of the cache-miss handling:
661
662      __mf_check();
663      refresh *_l vars.
664
665      This is the body of the conditional.  */
666
667   u = mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION : *locus);
668   /* NB: we pass the overall [base..limit] range to mf_check.  */
669   v = fold_build2 (PLUS_EXPR, integer_type_node,
670                    fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
671                    integer_one_node);
672   t = build_call_expr (mf_check_fndecl, 4, mf_base, v, dirflag, u);
673   gimplify_to_stmt_list (&t);
674   head = tsi_start (t);
675   tsi = tsi_last (t);
676
677   if (! flag_mudflap_threads)
678     {
679       t = build_gimple_modify_stmt (mf_cache_shift_decl_l,
680                                     mf_cache_shift_decl);
681       tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
682
683       t = build_gimple_modify_stmt (mf_cache_mask_decl_l,
684                                     mf_cache_mask_decl);
685       tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
686     }
687
688   /* Insert the check code in the THEN block.  */
689   bsi = bsi_start (then_bb);
690   for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
691     bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
692
693   *instr_bsi = bsi_start (join_bb);
694 }
695
696
697 /* Check whether the given decl, generally a VAR_DECL or PARM_DECL, is
698    eligible for instrumentation.  For the mudflap1 pass, this implies
699    that it should be registered with the libmudflap runtime.  For the
700    mudflap2 pass this means instrumenting an indirection operation with
701    respect to the object.
702 */
703 static int
704 mf_decl_eligible_p (tree decl)
705 {
706   return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
707           /* The decl must have its address taken.  In the case of
708              arrays, this flag is also set if the indexes are not
709              compile-time known valid constants.  */
710           /* XXX: not sufficient: return-by-value structs! */
711           && TREE_ADDRESSABLE (decl)
712           /* The type of the variable must be complete.  */
713           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
714           /* The decl hasn't been decomposed somehow.  */
715           && !DECL_HAS_VALUE_EXPR_P (decl));
716 }
717
718
719 static void
720 mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
721                    location_t *locus, tree dirflag)
722 {
723   tree type, base, limit, addr, size, t;
724
725   /* Don't instrument read operations.  */
726   if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
727     return;
728
729   /* Don't instrument marked nodes.  */
730   if (mf_marked_p (*tp))
731     return;
732
733   t = *tp;
734   type = TREE_TYPE (t);
735
736   if (type == error_mark_node)
737     return;
738
739   size = TYPE_SIZE_UNIT (type);
740
741   switch (TREE_CODE (t))
742     {
743     case ARRAY_REF:
744     case COMPONENT_REF:
745       {
746         /* This is trickier than it may first appear.  The reason is
747            that we are looking at expressions from the "inside out" at
748            this point.  We may have a complex nested aggregate/array
749            expression (e.g. "a.b[i].c"), maybe with an indirection as
750            the leftmost operator ("p->a.b.d"), where instrumentation
751            is necessary.  Or we may have an innocent "a.b.c"
752            expression that must not be instrumented.  We need to
753            recurse all the way down the nesting structure to figure it
754            out: looking just at the outer node is not enough.  */          
755         tree var;
756         int component_ref_only = (TREE_CODE (t) == COMPONENT_REF);
757         /* If we have a bitfield component reference, we must note the
758            innermost addressable object in ELT, from which we will
759            construct the byte-addressable bounds of the bitfield.  */
760         tree elt = NULL_TREE;
761         int bitfield_ref_p = (TREE_CODE (t) == COMPONENT_REF
762                               && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)));
763
764         /* Iterate to the top of the ARRAY_REF/COMPONENT_REF
765            containment hierarchy to find the outermost VAR_DECL.  */
766         var = TREE_OPERAND (t, 0);
767         while (1)
768           {
769             if (bitfield_ref_p && elt == NULL_TREE
770                 && (TREE_CODE (var) == ARRAY_REF
771                     || TREE_CODE (var) == COMPONENT_REF))
772               elt = var;
773         
774             if (TREE_CODE (var) == ARRAY_REF)
775               {
776                 component_ref_only = 0;
777                 var = TREE_OPERAND (var, 0);
778               }
779             else if (TREE_CODE (var) == COMPONENT_REF)
780               var = TREE_OPERAND (var, 0);
781             else if (INDIRECT_REF_P (var))
782               {
783                 base = TREE_OPERAND (var, 0);
784                 break;
785               }
786             else 
787               {
788                 gcc_assert (TREE_CODE (var) == VAR_DECL 
789                             || TREE_CODE (var) == PARM_DECL
790                             || TREE_CODE (var) == RESULT_DECL
791                             || TREE_CODE (var) == STRING_CST);
792                 /* Don't instrument this access if the underlying
793                    variable is not "eligible".  This test matches
794                    those arrays that have only known-valid indexes,
795                    and thus are not labeled TREE_ADDRESSABLE.  */
796                 if (! mf_decl_eligible_p (var) || component_ref_only)
797                   return;
798                 else
799                   {
800                     base = build1 (ADDR_EXPR,
801                                    build_pointer_type (TREE_TYPE (var)), var);
802                     break;
803                   }
804               }
805           }
806
807         /* Handle the case of ordinary non-indirection structure
808            accesses.  These have only nested COMPONENT_REF nodes (no
809            INDIRECT_REF), but pass through the above filter loop.
810            Note that it's possible for such a struct variable to match
811            the eligible_p test because someone else might take its
812            address sometime.  */
813
814         /* We need special processing for bitfield components, because
815            their addresses cannot be taken.  */
816         if (bitfield_ref_p)
817           {
818             tree field = TREE_OPERAND (t, 1);
819
820             if (TREE_CODE (DECL_SIZE_UNIT (field)) == INTEGER_CST)
821               size = DECL_SIZE_UNIT (field);
822             
823             if (elt)
824               elt = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (elt)),
825                             elt);
826             addr = fold_convert (ptr_type_node, elt ? elt : base);
827             addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
828                                 addr, fold_convert (sizetype,
829                                                     byte_position (field)));
830           }
831         else
832           addr = build1 (ADDR_EXPR, build_pointer_type (type), t);
833
834         limit = fold_build2 (MINUS_EXPR, mf_uintptr_type,
835                              fold_build2 (PLUS_EXPR, mf_uintptr_type,
836                                           convert (mf_uintptr_type, addr),
837                                           size),
838                              integer_one_node);
839       }
840       break;
841
842     case INDIRECT_REF:
843       addr = TREE_OPERAND (t, 0);
844       base = addr;
845       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
846                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
847                                         size),
848                            size_int (-1));
849       break;
850
851     case TARGET_MEM_REF:
852       addr = tree_mem_ref_addr (ptr_type_node, t);
853       base = addr;
854       limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
855                            fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base,
856                                         size),
857                            size_int (-1));
858       break;
859
860     case ARRAY_RANGE_REF:
861       warning (OPT_Wmudflap,
862                "mudflap checking not yet implemented for ARRAY_RANGE_REF");
863       return;
864
865     case BIT_FIELD_REF:
866       /* ??? merge with COMPONENT_REF code above? */
867       {
868         tree ofs, rem, bpu;
869
870         /* If we're not dereferencing something, then the access
871            must be ok.  */
872         if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
873           return;
874
875         bpu = bitsize_int (BITS_PER_UNIT);
876         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
877         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
878         ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
879
880         size = convert (bitsizetype, TREE_OPERAND (t, 1));
881         size = size_binop (PLUS_EXPR, size, rem);
882         size = size_binop (CEIL_DIV_EXPR, size, bpu);
883         size = convert (sizetype, size);
884
885         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
886         addr = convert (ptr_type_node, addr);
887         addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
888
889         base = addr;
890         limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
891                              fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
892                                            base, size),
893                              size_int (-1));
894       }
895       break;
896
897     default:
898       return;
899     }
900
901   mf_build_check_statement_for (base, limit, iter, locus, dirflag);
902 }
903
904 static void
905 mf_xform_derefs (void)
906 {
907   basic_block bb, next;
908   block_stmt_iterator i;
909   int saved_last_basic_block = last_basic_block;
910
911   bb = ENTRY_BLOCK_PTR ->next_bb;
912   do
913     {
914       next = bb->next_bb;
915       for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
916         {
917           tree s = bsi_stmt (i);
918
919           /* Only a few GIMPLE statements can reference memory.  */
920           switch (TREE_CODE (s))
921             {
922             case GIMPLE_MODIFY_STMT:
923               mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 0),
924                                  EXPR_LOCUS (s), integer_one_node);
925               mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 1),
926                                  EXPR_LOCUS (s), integer_zero_node);
927               break;
928
929             case RETURN_EXPR:
930               if (TREE_OPERAND (s, 0) != NULL_TREE)
931                 {
932                   if (TREE_CODE (TREE_OPERAND (s, 0)) == GIMPLE_MODIFY_STMT)
933                     mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND
934                                              (TREE_OPERAND (s, 0), 1),
935                                        EXPR_LOCUS (s), integer_zero_node);
936                   else
937                     mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
938                                        integer_zero_node);
939                 }
940               break;
941
942             default:
943               ;
944             }
945         }
946       bb = next;
947     }
948   while (bb && bb->index <= saved_last_basic_block);
949 }
950
951 /* ------------------------------------------------------------------------ */
952 /* ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
953    transforms on the current function.
954
955    This is the first part of the mudflap instrumentation.  It works on
956    high-level GIMPLE because after lowering, all variables are moved out
957    of their BIND_EXPR binding context, and we lose liveness information
958    for the declarations we wish to instrument.  */
959
960 static unsigned int
961 execute_mudflap_function_decls (void)
962 {
963   struct gimplify_ctx gctx;
964
965   /* Don't instrument functions such as the synthetic constructor
966      built during mudflap_finish_file.  */
967   if (mf_marked_p (current_function_decl) ||
968       DECL_ARTIFICIAL (current_function_decl))
969     return 0;
970
971   push_gimplify_context (&gctx);
972
973   mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
974                   DECL_ARGUMENTS (current_function_decl));
975
976   pop_gimplify_context (NULL);
977   return 0;
978 }
979
980 /* This struct is passed between mf_xform_decls to store state needed
981    during the traversal searching for objects that have their
982    addresses taken.  */
983 struct mf_xform_decls_data
984 {
985   tree param_decls;
986 };
987
988
989 /* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
990    _DECLs if appropriate.  Arrange to call the __mf_register function
991    now, and the __mf_unregister function later for each.  */
992 static void
993 mx_register_decls (tree decl, tree *stmt_list)
994 {
995   tree finally_stmts = NULL_TREE;
996   tree_stmt_iterator initially_stmts = tsi_start (*stmt_list);
997
998   while (decl != NULL_TREE)
999     {
1000       if (mf_decl_eligible_p (decl) 
1001           /* Not already processed.  */
1002           && ! mf_marked_p (decl)
1003           /* Automatic variable.  */
1004           && ! DECL_EXTERNAL (decl)
1005           && ! TREE_STATIC (decl))
1006         {
1007           tree size = NULL_TREE, variable_name;
1008           tree unregister_fncall, unregister_fncall_param;
1009           tree register_fncall, register_fncall_param;
1010
1011           size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
1012
1013
1014           unregister_fncall_param =
1015             convert (ptr_type_node,
1016                      mf_mark (build1 (ADDR_EXPR,
1017                                       build_pointer_type (TREE_TYPE (decl)),
1018                                       decl)));
1019           /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
1020           unregister_fncall = build_call_expr (mf_unregister_fndecl, 3,
1021                                                unregister_fncall_param,
1022                                                size,
1023                                                build_int_cst (NULL_TREE, 3));
1024
1025
1026           variable_name = mf_varname_tree (decl);
1027           register_fncall_param =
1028             convert (ptr_type_node,
1029                      mf_mark (build1 (ADDR_EXPR,
1030                                       build_pointer_type (TREE_TYPE (decl)),
1031                                       decl)));
1032           /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
1033                             "name") */
1034           register_fncall = build_call_expr (mf_register_fndecl, 4,
1035                                              register_fncall_param,
1036                                              size,
1037                                              build_int_cst (NULL_TREE, 3),
1038                                              variable_name);
1039
1040
1041           /* Accumulate the two calls.  */
1042           /* ??? Set EXPR_LOCATION.  */
1043           gimplify_stmt (&register_fncall);
1044           gimplify_stmt (&unregister_fncall);
1045
1046           /* Add the __mf_register call at the current appending point.  */
1047           if (tsi_end_p (initially_stmts))
1048             {
1049               if (!DECL_ARTIFICIAL (decl))
1050                 warning (OPT_Wmudflap,
1051                          "mudflap cannot track %qs in stub function",
1052                          IDENTIFIER_POINTER (DECL_NAME (decl)));
1053             }
1054           else
1055             {
1056               tsi_link_before (&initially_stmts, register_fncall,
1057                                TSI_SAME_STMT);
1058
1059               /* Accumulate the FINALLY piece.  */
1060               append_to_statement_list (unregister_fncall, &finally_stmts);
1061             }
1062           mf_mark (decl);
1063         }
1064
1065       decl = TREE_CHAIN (decl);
1066     }
1067
1068   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
1069   if (finally_stmts != NULL_TREE)
1070     {
1071       tree t = build2 (TRY_FINALLY_EXPR, void_type_node,
1072                        *stmt_list, finally_stmts);
1073       *stmt_list = NULL;
1074       append_to_statement_list (t, stmt_list);
1075     }
1076 }
1077
1078
1079 /* Process every variable mentioned in BIND_EXPRs.  */
1080 static tree
1081 mx_xfn_xform_decls (tree *t, int *continue_p, void *data)
1082 {
1083   struct mf_xform_decls_data* d = (struct mf_xform_decls_data*) data;
1084
1085   if (*t == NULL_TREE || *t == error_mark_node)
1086     {
1087       *continue_p = 0;
1088       return NULL_TREE;
1089     }
1090
1091   *continue_p = 1;
1092
1093   switch (TREE_CODE (*t))
1094     {
1095     case BIND_EXPR:
1096       {
1097         /* Process function parameters now (but only once).  */
1098         mx_register_decls (d->param_decls, &BIND_EXPR_BODY (*t));
1099         d->param_decls = NULL_TREE;
1100
1101         mx_register_decls (BIND_EXPR_VARS (*t), &BIND_EXPR_BODY (*t));
1102       }
1103       break;
1104
1105     default:
1106       break;
1107     }
1108
1109   return NULL_TREE;
1110 }
1111
1112 /* Perform the object lifetime tracking mudflap transform on the given function
1113    tree.  The tree is mutated in place, with possibly copied subtree nodes.
1114
1115    For every auto variable declared, if its address is ever taken
1116    within the function, then supply its lifetime to the mudflap
1117    runtime with the __mf_register and __mf_unregister calls.
1118 */
1119
1120 static void
1121 mf_xform_decls (tree fnbody, tree fnparams)
1122 {
1123   struct mf_xform_decls_data d;
1124   d.param_decls = fnparams;
1125   walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d);
1126 }
1127
1128
1129 /* ------------------------------------------------------------------------ */
1130 /* Externally visible mudflap functions.  */
1131
1132
1133 /* Mark and return the given tree node to prevent further mudflap
1134    transforms.  */
1135 static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
1136
1137 tree
1138 mf_mark (tree t)
1139 {
1140   void **slot;
1141
1142   if (marked_trees == NULL)
1143     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer,
1144                                     NULL);
1145
1146   slot = htab_find_slot (marked_trees, t, INSERT);
1147   *slot = t;
1148   return t;
1149 }
1150
1151 int
1152 mf_marked_p (tree t)
1153 {
1154   void *entry;
1155
1156   if (marked_trees == NULL)
1157     return 0;
1158
1159   entry = htab_find (marked_trees, t);
1160   return (entry != NULL);
1161 }
1162
1163 /* Remember given node as a static of some kind: global data,
1164    function-scope static, or an anonymous constant.  Its assembler
1165    label is given.  */
1166
1167 /* A list of globals whose incomplete declarations we encountered.
1168    Instead of emitting the __mf_register call for them here, it's
1169    delayed until program finish time.  If they're still incomplete by
1170    then, warnings are emitted.  */
1171
1172 static GTY (()) VEC(tree,gc) *deferred_static_decls;
1173
1174 /* A list of statements for calling __mf_register() at startup time.  */
1175 static GTY (()) tree enqueued_call_stmt_chain;
1176
1177 static void
1178 mudflap_register_call (tree obj, tree object_size, tree varname)
1179 {
1180   tree arg, call_stmt;
1181
1182   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
1183   arg = convert (ptr_type_node, arg);
1184
1185   call_stmt = build_call_expr (mf_register_fndecl, 4,
1186                                arg,
1187                                convert (size_type_node, object_size),
1188                                /* __MF_TYPE_STATIC */
1189                                build_int_cst (NULL_TREE, 4), 
1190                                varname);
1191
1192   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
1193 }
1194
1195 void
1196 mudflap_enqueue_decl (tree obj)
1197 {
1198   if (mf_marked_p (obj))
1199     return;
1200
1201   /* We don't need to process variable decls that are internally
1202      generated extern.  If we did, we'd end up with warnings for them
1203      during mudflap_finish_file ().  That would confuse the user,
1204      since the text would refer to variables that don't show up in the
1205      user's source code.  */
1206   if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
1207     return;
1208
1209   VEC_safe_push (tree, gc, deferred_static_decls, obj);
1210 }
1211
1212
1213 void
1214 mudflap_enqueue_constant (tree obj)
1215 {
1216   tree object_size, varname;
1217
1218   if (mf_marked_p (obj))
1219     return;
1220
1221   if (TREE_CODE (obj) == STRING_CST)
1222     object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
1223   else
1224     object_size = size_in_bytes (TREE_TYPE (obj));
1225
1226   if (TREE_CODE (obj) == STRING_CST)
1227     varname = mf_build_string ("string literal");
1228   else
1229     varname = mf_build_string ("constant");
1230
1231   mudflap_register_call (obj, object_size, varname);
1232 }
1233
1234
1235 /* Emit any file-wide instrumentation.  */
1236 void
1237 mudflap_finish_file (void)
1238 {
1239   tree ctor_statements = NULL_TREE;
1240
1241   /* No need to continue when there were errors.  */
1242   if (errorcount != 0 || sorrycount != 0)
1243     return;
1244
1245   /* Insert a call to __mf_init.  */
1246   {
1247     tree call2_stmt = build_call_expr (mf_init_fndecl, 0);
1248     append_to_statement_list (call2_stmt, &ctor_statements);
1249   }
1250   
1251   /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
1252   if (flag_mudflap_ignore_reads)
1253     {
1254       tree arg = mf_build_string ("-ignore-reads");
1255       tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg);
1256       append_to_statement_list (call_stmt, &ctor_statements);
1257     }
1258
1259   /* Process all enqueued object decls.  */
1260   if (deferred_static_decls)
1261     {
1262       size_t i;
1263       tree obj;
1264       for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
1265         {
1266           gcc_assert (DECL_P (obj));
1267
1268           if (mf_marked_p (obj))
1269             continue;
1270
1271           /* Omit registration for static unaddressed objects.  NB:
1272              Perform registration for non-static objects regardless of
1273              TREE_USED or TREE_ADDRESSABLE, because they may be used
1274              from other compilation units.  */
1275           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
1276             continue;
1277
1278           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
1279             {
1280               warning (OPT_Wmudflap,
1281                        "mudflap cannot track unknown size extern %qs",
1282                        IDENTIFIER_POINTER (DECL_NAME (obj)));
1283               continue;
1284             }
1285           
1286           mudflap_register_call (obj, 
1287                                  size_in_bytes (TREE_TYPE (obj)),
1288                                  mf_varname_tree (obj));
1289         }
1290
1291       VEC_truncate (tree, deferred_static_decls, 0);
1292     }
1293
1294   /* Append all the enqueued registration calls.  */
1295   if (enqueued_call_stmt_chain)
1296     {
1297       append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
1298       enqueued_call_stmt_chain = NULL_TREE;
1299     }
1300
1301   cgraph_build_static_cdtor ('I', ctor_statements, 
1302                              MAX_RESERVED_INIT_PRIORITY-1);
1303 }
1304
1305
1306 static bool
1307 gate_mudflap (void)
1308 {
1309   return flag_mudflap != 0;
1310 }
1311
1312 struct gimple_opt_pass pass_mudflap_1 = 
1313 {
1314  {
1315   GIMPLE_PASS,
1316   "mudflap1",                           /* name */
1317   gate_mudflap,                         /* gate */
1318   execute_mudflap_function_decls,       /* execute */
1319   NULL,                                 /* sub */
1320   NULL,                                 /* next */
1321   0,                                    /* static_pass_number */
1322   0,                                    /* tv_id */
1323   PROP_gimple_any,                      /* properties_required */
1324   0,                                    /* properties_provided */
1325   0,                                    /* properties_destroyed */
1326   0,                                    /* todo_flags_start */
1327   TODO_dump_func                        /* todo_flags_finish */
1328  }
1329 };
1330
1331 struct gimple_opt_pass pass_mudflap_2 = 
1332 {
1333  {
1334   GIMPLE_PASS,
1335   "mudflap2",                           /* name */
1336   gate_mudflap,                         /* gate */
1337   execute_mudflap_function_ops,         /* execute */
1338   NULL,                                 /* sub */
1339   NULL,                                 /* next */
1340   0,                                    /* static_pass_number */
1341   0,                                    /* tv_id */
1342   PROP_gimple_leh,                      /* properties_required */
1343   0,                                    /* properties_provided */
1344   0,                                    /* properties_destroyed */
1345   0,                                    /* todo_flags_start */
1346   TODO_verify_flow | TODO_verify_stmts
1347   | TODO_dump_func                      /* todo_flags_finish */
1348  }
1349 };
1350
1351 #include "gt-tree-mudflap.h"