OSDN Git Service

PR testsuite/34168
[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 (OPT_Wmudflap,
861                "mudflap checking not yet implemented for ARRAY_RANGE_REF");
862       return;
863
864     case BIT_FIELD_REF:
865       /* ??? merge with COMPONENT_REF code above? */
866       {
867         tree ofs, rem, bpu;
868
869         /* If we're not dereferencing something, then the access
870            must be ok.  */
871         if (TREE_CODE (TREE_OPERAND (t, 0)) != INDIRECT_REF)
872           return;
873
874         bpu = bitsize_int (BITS_PER_UNIT);
875         ofs = convert (bitsizetype, TREE_OPERAND (t, 2));
876         rem = size_binop (TRUNC_MOD_EXPR, ofs, bpu);
877         ofs = fold_convert (sizetype, size_binop (TRUNC_DIV_EXPR, ofs, bpu));
878
879         size = convert (bitsizetype, TREE_OPERAND (t, 1));
880         size = size_binop (PLUS_EXPR, size, rem);
881         size = size_binop (CEIL_DIV_EXPR, size, bpu);
882         size = convert (sizetype, size);
883
884         addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
885         addr = convert (ptr_type_node, addr);
886         addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, ofs);
887
888         base = addr;
889         limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
890                              fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
891                                            base, size),
892                              size_int (-1));
893       }
894       break;
895
896     default:
897       return;
898     }
899
900   mf_build_check_statement_for (base, limit, iter, locus, dirflag);
901 }
902
903 static void
904 mf_xform_derefs (void)
905 {
906   basic_block bb, next;
907   block_stmt_iterator i;
908   int saved_last_basic_block = last_basic_block;
909
910   bb = ENTRY_BLOCK_PTR ->next_bb;
911   do
912     {
913       next = bb->next_bb;
914       for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
915         {
916           tree s = bsi_stmt (i);
917
918           /* Only a few GIMPLE statements can reference memory.  */
919           switch (TREE_CODE (s))
920             {
921             case GIMPLE_MODIFY_STMT:
922               mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 0),
923                                  EXPR_LOCUS (s), integer_one_node);
924               mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 1),
925                                  EXPR_LOCUS (s), integer_zero_node);
926               break;
927
928             case RETURN_EXPR:
929               if (TREE_OPERAND (s, 0) != NULL_TREE)
930                 {
931                   if (TREE_CODE (TREE_OPERAND (s, 0)) == GIMPLE_MODIFY_STMT)
932                     mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND
933                                              (TREE_OPERAND (s, 0), 1),
934                                        EXPR_LOCUS (s), integer_zero_node);
935                   else
936                     mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
937                                        integer_zero_node);
938                 }
939               break;
940
941             default:
942               ;
943             }
944         }
945       bb = next;
946     }
947   while (bb && bb->index <= saved_last_basic_block);
948 }
949
950 /* ------------------------------------------------------------------------ */
951 /* ADDR_EXPR transforms.  Perform the declaration-related mudflap tree
952    transforms on the current function.
953
954    This is the first part of the mudflap instrumentation.  It works on
955    high-level GIMPLE because after lowering, all variables are moved out
956    of their BIND_EXPR binding context, and we lose liveness information
957    for the declarations we wish to instrument.  */
958
959 static unsigned int
960 execute_mudflap_function_decls (void)
961 {
962   /* Don't instrument functions such as the synthetic constructor
963      built during mudflap_finish_file.  */
964   if (mf_marked_p (current_function_decl) ||
965       DECL_ARTIFICIAL (current_function_decl))
966     return 0;
967
968   push_gimplify_context ();
969
970   mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
971                   DECL_ARGUMENTS (current_function_decl));
972
973   pop_gimplify_context (NULL);
974   return 0;
975 }
976
977 /* This struct is passed between mf_xform_decls to store state needed
978    during the traversal searching for objects that have their
979    addresses taken.  */
980 struct mf_xform_decls_data
981 {
982   tree param_decls;
983 };
984
985
986 /* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
987    _DECLs if appropriate.  Arrange to call the __mf_register function
988    now, and the __mf_unregister function later for each.  */
989 static void
990 mx_register_decls (tree decl, tree *stmt_list)
991 {
992   tree finally_stmts = NULL_TREE;
993   tree_stmt_iterator initially_stmts = tsi_start (*stmt_list);
994
995   while (decl != NULL_TREE)
996     {
997       if (mf_decl_eligible_p (decl) 
998           /* Not already processed.  */
999           && ! mf_marked_p (decl)
1000           /* Automatic variable.  */
1001           && ! DECL_EXTERNAL (decl)
1002           && ! TREE_STATIC (decl))
1003         {
1004           tree size = NULL_TREE, variable_name;
1005           tree unregister_fncall, unregister_fncall_param;
1006           tree register_fncall, register_fncall_param;
1007
1008           size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
1009
1010
1011           unregister_fncall_param =
1012             convert (ptr_type_node,
1013                      mf_mark (build1 (ADDR_EXPR,
1014                                       build_pointer_type (TREE_TYPE (decl)),
1015                                       decl)));
1016           /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
1017           unregister_fncall = build_call_expr (mf_unregister_fndecl, 3,
1018                                                unregister_fncall_param,
1019                                                size,
1020                                                build_int_cst (NULL_TREE, 3));
1021
1022
1023           variable_name = mf_varname_tree (decl);
1024           register_fncall_param =
1025             convert (ptr_type_node,
1026                      mf_mark (build1 (ADDR_EXPR,
1027                                       build_pointer_type (TREE_TYPE (decl)),
1028                                       decl)));
1029           /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
1030                             "name") */
1031           register_fncall = build_call_expr (mf_register_fndecl, 4,
1032                                              register_fncall_param,
1033                                              size,
1034                                              build_int_cst (NULL_TREE, 3),
1035                                              variable_name);
1036
1037
1038           /* Accumulate the two calls.  */
1039           /* ??? Set EXPR_LOCATION.  */
1040           gimplify_stmt (&register_fncall);
1041           gimplify_stmt (&unregister_fncall);
1042
1043           /* Add the __mf_register call at the current appending point.  */
1044           if (tsi_end_p (initially_stmts))
1045             {
1046               if (!DECL_ARTIFICIAL (decl))
1047                 warning (OPT_Wmudflap,
1048                          "mudflap cannot track %qs in stub function",
1049                          IDENTIFIER_POINTER (DECL_NAME (decl)));
1050             }
1051           else
1052             {
1053               tsi_link_before (&initially_stmts, register_fncall,
1054                                TSI_SAME_STMT);
1055
1056               /* Accumulate the FINALLY piece.  */
1057               append_to_statement_list (unregister_fncall, &finally_stmts);
1058             }
1059           mf_mark (decl);
1060         }
1061
1062       decl = TREE_CHAIN (decl);
1063     }
1064
1065   /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
1066   if (finally_stmts != NULL_TREE)
1067     {
1068       tree t = build2 (TRY_FINALLY_EXPR, void_type_node,
1069                        *stmt_list, finally_stmts);
1070       *stmt_list = NULL;
1071       append_to_statement_list (t, stmt_list);
1072     }
1073 }
1074
1075
1076 /* Process every variable mentioned in BIND_EXPRs.  */
1077 static tree
1078 mx_xfn_xform_decls (tree *t, int *continue_p, void *data)
1079 {
1080   struct mf_xform_decls_data* d = (struct mf_xform_decls_data*) data;
1081
1082   if (*t == NULL_TREE || *t == error_mark_node)
1083     {
1084       *continue_p = 0;
1085       return NULL_TREE;
1086     }
1087
1088   *continue_p = 1;
1089
1090   switch (TREE_CODE (*t))
1091     {
1092     case BIND_EXPR:
1093       {
1094         /* Process function parameters now (but only once).  */
1095         mx_register_decls (d->param_decls, &BIND_EXPR_BODY (*t));
1096         d->param_decls = NULL_TREE;
1097
1098         mx_register_decls (BIND_EXPR_VARS (*t), &BIND_EXPR_BODY (*t));
1099       }
1100       break;
1101
1102     default:
1103       break;
1104     }
1105
1106   return NULL_TREE;
1107 }
1108
1109 /* Perform the object lifetime tracking mudflap transform on the given function
1110    tree.  The tree is mutated in place, with possibly copied subtree nodes.
1111
1112    For every auto variable declared, if its address is ever taken
1113    within the function, then supply its lifetime to the mudflap
1114    runtime with the __mf_register and __mf_unregister calls.
1115 */
1116
1117 static void
1118 mf_xform_decls (tree fnbody, tree fnparams)
1119 {
1120   struct mf_xform_decls_data d;
1121   d.param_decls = fnparams;
1122   walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d);
1123 }
1124
1125
1126 /* ------------------------------------------------------------------------ */
1127 /* Externally visible mudflap functions.  */
1128
1129
1130 /* Mark and return the given tree node to prevent further mudflap
1131    transforms.  */
1132 static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL;
1133
1134 tree
1135 mf_mark (tree t)
1136 {
1137   void **slot;
1138
1139   if (marked_trees == NULL)
1140     marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer,
1141                                     NULL);
1142
1143   slot = htab_find_slot (marked_trees, t, INSERT);
1144   *slot = t;
1145   return t;
1146 }
1147
1148 int
1149 mf_marked_p (tree t)
1150 {
1151   void *entry;
1152
1153   if (marked_trees == NULL)
1154     return 0;
1155
1156   entry = htab_find (marked_trees, t);
1157   return (entry != NULL);
1158 }
1159
1160 /* Remember given node as a static of some kind: global data,
1161    function-scope static, or an anonymous constant.  Its assembler
1162    label is given.  */
1163
1164 /* A list of globals whose incomplete declarations we encountered.
1165    Instead of emitting the __mf_register call for them here, it's
1166    delayed until program finish time.  If they're still incomplete by
1167    then, warnings are emitted.  */
1168
1169 static GTY (()) VEC(tree,gc) *deferred_static_decls;
1170
1171 /* A list of statements for calling __mf_register() at startup time.  */
1172 static GTY (()) tree enqueued_call_stmt_chain;
1173
1174 static void
1175 mudflap_register_call (tree obj, tree object_size, tree varname)
1176 {
1177   tree arg, call_stmt;
1178
1179   arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (obj)), obj);
1180   arg = convert (ptr_type_node, arg);
1181
1182   call_stmt = build_call_expr (mf_register_fndecl, 4,
1183                                arg,
1184                                convert (size_type_node, object_size),
1185                                /* __MF_TYPE_STATIC */
1186                                build_int_cst (NULL_TREE, 4), 
1187                                varname);
1188
1189   append_to_statement_list (call_stmt, &enqueued_call_stmt_chain);
1190 }
1191
1192 void
1193 mudflap_enqueue_decl (tree obj)
1194 {
1195   if (mf_marked_p (obj))
1196     return;
1197
1198   /* We don't need to process variable decls that are internally
1199      generated extern.  If we did, we'd end up with warnings for them
1200      during mudflap_finish_file ().  That would confuse the user,
1201      since the text would refer to variables that don't show up in the
1202      user's source code.  */
1203   if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj))
1204     return;
1205
1206   VEC_safe_push (tree, gc, deferred_static_decls, obj);
1207 }
1208
1209
1210 void
1211 mudflap_enqueue_constant (tree obj)
1212 {
1213   tree object_size, varname;
1214
1215   if (mf_marked_p (obj))
1216     return;
1217
1218   if (TREE_CODE (obj) == STRING_CST)
1219     object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj));
1220   else
1221     object_size = size_in_bytes (TREE_TYPE (obj));
1222
1223   if (TREE_CODE (obj) == STRING_CST)
1224     varname = mf_build_string ("string literal");
1225   else
1226     varname = mf_build_string ("constant");
1227
1228   mudflap_register_call (obj, object_size, varname);
1229 }
1230
1231
1232 /* Emit any file-wide instrumentation.  */
1233 void
1234 mudflap_finish_file (void)
1235 {
1236   tree ctor_statements = NULL_TREE;
1237
1238   /* No need to continue when there were errors.  */
1239   if (errorcount != 0 || sorrycount != 0)
1240     return;
1241
1242   /* Insert a call to __mf_init.  */
1243   {
1244     tree call2_stmt = build_call_expr (mf_init_fndecl, 0);
1245     append_to_statement_list (call2_stmt, &ctor_statements);
1246   }
1247   
1248   /* If appropriate, call __mf_set_options to pass along read-ignore mode.  */
1249   if (flag_mudflap_ignore_reads)
1250     {
1251       tree arg = mf_build_string ("-ignore-reads");
1252       tree call_stmt = build_call_expr (mf_set_options_fndecl, 1, arg);
1253       append_to_statement_list (call_stmt, &ctor_statements);
1254     }
1255
1256   /* Process all enqueued object decls.  */
1257   if (deferred_static_decls)
1258     {
1259       size_t i;
1260       tree obj;
1261       for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++)
1262         {
1263           gcc_assert (DECL_P (obj));
1264
1265           if (mf_marked_p (obj))
1266             continue;
1267
1268           /* Omit registration for static unaddressed objects.  NB:
1269              Perform registration for non-static objects regardless of
1270              TREE_USED or TREE_ADDRESSABLE, because they may be used
1271              from other compilation units.  */
1272           if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj))
1273             continue;
1274
1275           if (! COMPLETE_TYPE_P (TREE_TYPE (obj)))
1276             {
1277               warning (OPT_Wmudflap,
1278                        "mudflap cannot track unknown size extern %qs",
1279                        IDENTIFIER_POINTER (DECL_NAME (obj)));
1280               continue;
1281             }
1282           
1283           mudflap_register_call (obj, 
1284                                  size_in_bytes (TREE_TYPE (obj)),
1285                                  mf_varname_tree (obj));
1286         }
1287
1288       VEC_truncate (tree, deferred_static_decls, 0);
1289     }
1290
1291   /* Append all the enqueued registration calls.  */
1292   if (enqueued_call_stmt_chain)
1293     {
1294       append_to_statement_list (enqueued_call_stmt_chain, &ctor_statements);
1295       enqueued_call_stmt_chain = NULL_TREE;
1296     }
1297
1298   cgraph_build_static_cdtor ('I', ctor_statements, 
1299                              MAX_RESERVED_INIT_PRIORITY-1);
1300 }
1301
1302
1303 static bool
1304 gate_mudflap (void)
1305 {
1306   return flag_mudflap != 0;
1307 }
1308
1309 struct gimple_opt_pass pass_mudflap_1 = 
1310 {
1311  {
1312   GIMPLE_PASS,
1313   "mudflap1",                           /* name */
1314   gate_mudflap,                         /* gate */
1315   execute_mudflap_function_decls,       /* execute */
1316   NULL,                                 /* sub */
1317   NULL,                                 /* next */
1318   0,                                    /* static_pass_number */
1319   0,                                    /* tv_id */
1320   PROP_gimple_any,                      /* properties_required */
1321   0,                                    /* properties_provided */
1322   0,                                    /* properties_destroyed */
1323   0,                                    /* todo_flags_start */
1324   TODO_dump_func                        /* todo_flags_finish */
1325  }
1326 };
1327
1328 struct gimple_opt_pass pass_mudflap_2 = 
1329 {
1330  {
1331   GIMPLE_PASS,
1332   "mudflap2",                           /* name */
1333   gate_mudflap,                         /* gate */
1334   execute_mudflap_function_ops,         /* execute */
1335   NULL,                                 /* sub */
1336   NULL,                                 /* next */
1337   0,                                    /* static_pass_number */
1338   0,                                    /* tv_id */
1339   PROP_gimple_leh,                      /* properties_required */
1340   0,                                    /* properties_provided */
1341   0,                                    /* properties_destroyed */
1342   0,                                    /* todo_flags_start */
1343   TODO_verify_flow | TODO_verify_stmts
1344   | TODO_dump_func                      /* todo_flags_finish */
1345  }
1346 };
1347
1348 #include "gt-tree-mudflap.h"