OSDN Git Service

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