[tree-ssa mudflap] C++ front-end hooks

Frank Ch. Eigler fche@redhat.com
Mon Jan 13 23:09:00 GMT 2003


Hi -

The following patch adds some mudflap hooks to the C++ front-end.
It's just a start, but it already compiles & runs the C libmudflap test
suite properly.  It was necessary to factor out some code from
gcc/tree-mudflap.c into front-end-specific parts, thus the new
"c-mudflap.c" and "cp-mudflap.c" files.


Index: ChangeLog.tree-ssa
+ 2003-01-13  Frank Ch. Eigler  <fche@redhat.com>
+ 
+ 	Front-end generalization.
+ 	* Makefile.in (C_AND_OBJC_OBJS): Add c-mudflap.o and dependencies.
+ 	* tree-mudflap.c: Don't include "c-tree.h" any more.
+ 	(mf_init_extern_trees): Divert to mflang_lookup_decl().
+ 	(mf_enqueue_register_call, mf_flush_enqueued_calls): Move and rename
+ 	these functions.
+ 	* tree-mudflap.h: Declare new mflang_* routines.
+ 	* c-mudflap.c: New file with C front-end mflang_* routines.
+ 	* tree-nomudflap.c (*): Call internal_error instead of abort.
+ 

Index: cp/ChangeLog.tree-ssa
+ 2003-01-13  Frank Ch. Eigler  <fche@redhat.com>
+ 
+ 	Prototype C++ mudflap support.
+ 	* Make-lang.in (CXX_OBJS): Add cp/cp-mudflap.o and dependencies.
+ 	* cp-mudflap.c: New file with C++ front-end mflang_* routines.
+ 	* decl2.c (finish_file): Divert to mudflap if appropriate.
+ 	* optimize.c (optimize_function): Ditto.
+ 

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.62
diff -c -p -r1.903.2.62 Makefile.in
*** Makefile.in	10 Jan 2003 22:38:36 -0000	1.903.2.62
--- Makefile.in	13 Jan 2003 23:04:33 -0000
*************** CXX_TARGET_OBJS=@cxx_target_objs@
*** 738,744 ****
  C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
    c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
    c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS) \
!   c-simplify.o c-call-graph.o tree-mudflap.o c-pretty-print.o
  
  # Language-specific object files for C.
  C_OBJS = c-parse.o c-lang.o $(C_AND_OBJC_OBJS)
--- 738,744 ----
  C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
    c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
    c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS) \
!   c-simplify.o c-call-graph.o tree-mudflap.o c-mudflap.o c-pretty-print.o
  
  # Language-specific object files for C.
  C_OBJS = c-parse.o c-lang.o $(C_AND_OBJC_OBJS)
*************** c-call-graph.o : c-call-graph.c $(CONFIG
*** 1460,1465 ****
--- 1460,1468 ----
  tree-simple.o : tree-simple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
  	$(RTL_H) tree-simple.h $(TM_H) coretypes.h
  tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+    $(C_TREE_H) $(C_COMMON_H) tree-simple.h diagnostic.h $(HASHTAB_H) \
+    output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
+ c-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
     $(C_TREE_H) $(C_COMMON_H) tree-simple.h diagnostic.h $(HASHTAB_H) \
     output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
  tree-nomudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
Index: c-mudflap.c
===================================================================
RCS file: c-mudflap.c
diff -N c-mudflap.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- c-mudflap.c	13 Jan 2003 23:04:33 -0000
***************
*** 0 ****
--- 1,217 ----
+ /* Mudflap: narrow-pointer bounds-checking by tree rewriting: 
+    C front-end interface.
+ 
+    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+    Contributed by Frank Ch. Eigler <fche@redhat.com>
+    and Graydon Hoare <graydon@redhat.com>
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ 
+ #include "config.h"
+ #include "errors.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "tree-inline.h"
+ #include "c-tree.h"
+ #include "c-common.h"
+ #include "diagnostic.h"
+ #include "output.h"
+ #include "varray.h"
+ #include "tree-mudflap.h"
+ #include "target.h"
+ #include "flags.h"
+ #include "rtl.h"
+ #include "toplev.h"
+ #include "function.h"
+ 
+ 
+ 
+ /* ------------------------------------------------------------------------ */
+ 
+ static tree mx_flag PARAMS ((tree));
+ 
+ /* XXX: copied from tree-mudflap.c */
+ static tree
+ mx_flag (t)
+      tree t;
+ {
+   if (!t)
+     abort ();
+ #define MARK_TREE_MUDFLAPPED(tree)  do { TREE_BOUNDED (tree) = 1; } while (0)
+   MARK_TREE_MUDFLAPPED(t);
+   return t;
+ }
+ 
+ 
+ 
+ /* ------------------------------------------------------------------------ */
+ 
+ 
+ /* Initialize the global tree nodes that correspond to mf-runtime.h
+    declarations.  */
+ tree
+ mflang_lookup_decl (name)
+      const char* name;
+ {
+   tree decl = lookup_name (get_identifier (name));
+   if (decl == NULL_TREE)
+     internal_error ("mudflap: cannot find declaration of `%s' from mf-runtime.h", 
+ 		    name);
+ 
+   return decl;
+ }
+ 
+ 
+ 
+ /* Build and return EXPR_STMT for calling __mf_register on the object
+    given by the parameters.  One odd thing: the object's address is
+    given by the given assembler label string (since that's all we may
+    know about a string literal, or the static data thingie may be out
+    of the future scope).  To turn that into a validish C tree, we
+    create a weird synthetic VAR_DECL node.
+ */ 
+ 
+ tree
+ mflang_register_call (label, regsize, regtype, regname)
+      const char* label;
+      tree regsize;
+      tree regtype;
+      tree regname;
+ {
+   tree decltype, decl;
+   tree call_params;
+   tree call_stmt;
+ 
+   /* XXX: would be nicer not to duplicate these. */
+   tree mf_uintptr_type = TREE_TYPE (mflang_lookup_decl ("uintptr_t"));
+   tree mf_register_fndecl = mflang_lookup_decl ("__mf_register");
+ 
+   /* See gcc-checker's c-bounds.c (declare_private_statics)  */
+   decltype = build_array_type (char_type_node, build_index_type (integer_zero_node));
+   decl = mx_flag (build_decl (VAR_DECL, get_identifier (label), decltype));
+ 
+   TREE_STATIC (decl) = 1;
+   TREE_READONLY (decl) = 1;
+   TREE_ASM_WRITTEN (decl) = 1;
+   DECL_IGNORED_P (decl) = 1;
+   DECL_INITIAL (decl) = NULL_TREE;
+   layout_decl (decl, 0);
+   TREE_USED (decl) = 1;
+   SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
+   DECL_DEFER_OUTPUT (decl) = 1;
+   /* XXX: what else? */
+   /* rest_of_decl_compilation (decl, build_string (strlen (label) + 1, label), 1, 0); */
+   /* make_decl_rtl (decl,  build_string (strlen (label) + 1, label)); */
+ 
+   call_params = tree_cons (NULL_TREE,
+ 			   convert (mf_uintptr_type, 
+ 				    mx_flag (build1 (ADDR_EXPR, 
+ 						     build_pointer_type (TREE_TYPE (decl)),
+ 						     decl))),
+ 			   tree_cons (NULL_TREE, 
+ 				      convert (mf_uintptr_type, regsize),
+ 				      tree_cons (NULL_TREE,
+ 						 regtype,
+ 						 tree_cons (NULL_TREE,
+ 							    regname,
+ 							    NULL_TREE))));
+ 
+   call_stmt = build1 (EXPR_STMT, void_type_node,
+ 		      build_function_call (mf_register_fndecl,
+ 					   call_params));
+ 
+   return call_stmt;
+ }
+ 
+ 
+ 
+ /* Emit a synthetic CTOR function for the current file.  Populate it
+    from the enqueued __mf_register calls.  Call the RTL expanders
+    inline.  */
+ 
+ void
+ mflang_flush_calls (enqueued_call_stmt_chain)
+      tree enqueued_call_stmt_chain;
+ {
+   /* See profile.c (output_func_start_profiler) */
+   tree fnname;
+   char *nmplus;
+   tree fndecl;
+   tree body;
+ 
+   /* Short-circuit!  */
+   if (enqueued_call_stmt_chain == NULL_TREE)
+     return;
+ 
+   /* Create the COMPOUND_STMT that becomes the new function's body.  */
+   body = make_node (COMPOUND_STMT);
+   COMPOUND_BODY (body) = enqueued_call_stmt_chain;
+   enqueued_call_stmt_chain = NULL_TREE;
+ 
+   /* Create a ctor function declaration.  */
+   nmplus = concat (IDENTIFIER_POINTER (get_file_function_name ('I')), "_mudflap", NULL);
+   fnname = get_identifier (nmplus);
+   free (nmplus);
+   fndecl = build_decl (FUNCTION_DECL, fnname,
+ 		       build_function_type (void_type_node, NULL_TREE));
+   DECL_EXTERNAL (fndecl) = 0;
+   TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
+   TREE_USED (fndecl) = 1;
+   DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ 
+   /* Now compile the sucker as we go.  This is a weird semi-inlined
+   form of the guts of the c-parse.y `fndef' production, and a hybrid
+   with c_expand_body. */
+ 
+   /* start_function */
+   fndecl = pushdecl (fndecl);
+   pushlevel (0);
+   rest_of_decl_compilation (fndecl, 0, 1, 0);
+   announce_function (fndecl);
+   current_function_decl = fndecl;
+   DECL_INITIAL (fndecl) = error_mark_node;
+   DECL_SAVED_TREE (fndecl) = body;
+   make_decl_rtl (fndecl, NULL);
+ 
+   /* store_parm_decls */
+   init_function_start (fndecl, input_filename, lineno);
+   cfun->x_whole_function_mode_p = 1;
+ 
+   /* finish_function */
+   poplevel (1, 0, 1);
+   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ 
+   /* c_expand_body */
+   expand_function_start (fndecl, 0);
+   expand_stmt (DECL_SAVED_TREE (fndecl));
+   if (lang_expand_function_end)
+     (*lang_expand_function_end) ();
+   expand_function_end (input_filename, lineno, 0);
+   rest_of_compilation (fndecl);
+   if (! quiet_flag) 
+     fflush (asm_out_file);
+   current_function_decl = NULL_TREE;
+   if (targetm.have_ctors_dtors)
+     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
+                                      DEFAULT_INIT_PRIORITY);
+   else
+     static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+ }
Index: tree-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.c,v
retrieving revision 1.1.2.28
diff -c -p -r1.1.2.28 tree-mudflap.c
*** tree-mudflap.c	24 Dec 2002 03:14:36 -0000	1.1.2.28
--- tree-mudflap.c	13 Jan 2003 23:04:33 -0000
***************
*** 1,5 ****
  /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
!    Copyright (C) 2001, 2002 Free Software Foundation, Inc.
     Contributed by Frank Ch. Eigler <fche@redhat.com>
     and Graydon Hoare <graydon@redhat.com>
  
--- 1,5 ----
  /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
!    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
     Contributed by Frank Ch. Eigler <fche@redhat.com>
     and Graydon Hoare <graydon@redhat.com>
  
*************** Software Foundation, 59 Temple Place - S
*** 28,36 ****
  #include "tm.h"
  #include "tree.h"
  #include "tree-inline.h"
- #include "c-tree.h"
- #include "c-common.h"
  #include "tree-simple.h"
  #include "diagnostic.h"
  #include "hashtab.h"
  #include "output.h"
--- 28,35 ----
  #include "tm.h"
  #include "tree.h"
  #include "tree-inline.h"
  #include "tree-simple.h"
+ #include "c-common.h"
  #include "diagnostic.h"
  #include "hashtab.h"
  #include "output.h"
*************** static void mf_decl_cache_locals PARAMS 
*** 54,61 ****
  static void mf_decl_clear_locals PARAMS ((void));
  static tree mf_varname_tree PARAMS ((tree));
  static tree mf_file_function_line_tree PARAMS ((const char *, int));
- static void mf_enqueue_register_call PARAMS ((const char*, tree, tree, tree));
- static void mf_flush_enqueued_calls PARAMS ((void));
  static tree mf_mostly_copy_tree_r PARAMS ((tree *, int *, void *));
  static tree mx_flag PARAMS ((tree));
  static tree mx_xfn_indirect_ref PARAMS ((tree *, int *, void *));
--- 53,58 ----
*************** mudflap_c_function (t)
*** 109,244 ****
  }
  
  
- /* ------------------------------------------------------------------------ */
- 
- 
- /* Remember given node as a static of some kind: global data,
-    function-scope static, or an anonymous constant.  Its assembler
-    label is given.
- */
- 
- 
- /* A list of globals whose incomplete declarations we encountered.
-    Instead of emitting the __mf_register call for them here, it's
-    delayed until program finish time.  If they're still incomplete by
-    then, warnings are emitted.  */
- 
- static GTY (()) varray_type deferred_static_decls;
- static GTY (()) varray_type deferred_static_decl_labels;
- static int deferred_static_decls_init;
- 
- /* What I really want is a std::map<union tree_node,std::string> .. :-(  */
- 
- 
- void 
- mudflap_enqueue_decl (obj, label)
-      tree obj;
-      const char *label;
- {
-   if (TREE_MUDFLAPPED_P (obj))
-     return;
- 
-   /*
-   fprintf (stderr, "enqueue_decl obj=`");
-   print_generic_expr (stderr, obj, 0);
-   fprintf (stderr, "' label=`%s'\n", label);
-   */
- 
-   if (COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (obj))) 
-     {
-       /* NB: the above condition doesn't require TREE_USED or
-          TREE_ADDRESSABLE.  That's because this object may be a global
-          only used from other compilation units.  XXX: Maybe static
-          objects could require those attributes being set.  */
-       mf_enqueue_register_call (label,
- 				size_in_bytes (TREE_TYPE (obj)),
- 				build_int_2 (3, 0), /* __MF_TYPE_STATIC */
- 				mf_varname_tree (obj));
-     }
-   else
-     {
-       unsigned i;
-       int found_p;
-       
-       if (! deferred_static_decls_init)
- 	{
- 	  deferred_static_decls_init = 1;
- 	  VARRAY_TREE_INIT (deferred_static_decls, 10, "deferred static list");
- 	  VARRAY_CHAR_PTR_INIT (deferred_static_decl_labels, 10, "label list");
- 	}
-       
-       /* Ugh, linear search... */
-       found_p = 0;
-       for (i=0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
- 	if (VARRAY_TREE (deferred_static_decls, i) == obj)
- 	  found_p = 1;
-       
-       if (found_p)
- 	warning_with_decl (obj, "mudflap cannot track lifetime of `%s'", 
- 			   IDENTIFIER_POINTER (DECL_NAME (obj)));
-       else
- 	{
- 	  VARRAY_PUSH_TREE (deferred_static_decls, obj);
- 	  VARRAY_PUSH_CHAR_PTR (deferred_static_decl_labels, (char *) label);
- 	}
-     }
- }
- 
- 
- void 
- mudflap_enqueue_constant (obj, label)
-      tree obj;
-      const char *label;
- {
-   if (TREE_MUDFLAPPED_P (obj))
-     return;
- 
-   if (TREE_CODE (obj) == STRING_CST)
-     {
-       mf_enqueue_register_call (label,
- 				build_int_2 (TREE_STRING_LENGTH (obj), 0),
- 				build_int_2 (3, 0), /* __MF_TYPE_STATIC */
- 				mx_flag (fix_string_type
- 					 (build_string (15, "string literal"))));
-     }
-   else
-     {
-       mf_enqueue_register_call (label,
- 				size_in_bytes (TREE_TYPE (obj)),
- 				build_int_2 (3, 0), /* __MF_TYPE_STATIC */
- 				mx_flag (fix_string_type
- 					 (build_string (9, "constant"))));
-     }
- }
- 
- 
- 
- /* Emit any file-wide instrumentation.  */
- void 
- mudflap_finish_file ()
- {
-   /* Try to give the deferred objects one final try.  */
-   if (deferred_static_decls_init)
-     {
-       unsigned i;
- 
-       for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
- 	{
- 	  tree obj = VARRAY_TREE (deferred_static_decls, i);
- 	  const char *label = VARRAY_CHAR_PTR (deferred_static_decl_labels, i);
- 
- 	  /* Call enqueue_decl again on the same object it has previously
- 	     put into the table.  (It won't modify the table this time, so
- 	     infinite iteration is not a problem.)  */
- 	  mudflap_enqueue_decl (obj, label);
- 	}
- 
-       VARRAY_CLEAR (deferred_static_decls);
-       VARRAY_CLEAR (deferred_static_decl_labels);
-     }
- 	     
-   mf_flush_enqueued_calls ();
- }
  
  /* global tree nodes */
  
--- 106,111 ----
*************** static GTY (()) tree mf_unregister_fndec
*** 269,292 ****
  static void
  mf_init_extern_trees ()
  {
-   tree tmp;
- 
    static int done = 0;
-   if (done) return;
  
! #define mf_lookup_name(id) \
!   (tmp = lookup_name (id), \
!    (tmp ? tmp : (internal_error ("mudflap: cannot find declarations from mf-runtime.h"), tmp)))
  
!   mf_uintptr_type = TREE_TYPE (mf_lookup_name (get_identifier ("uintptr_t")));
!   mf_cache_struct_type = xref_tag (RECORD_TYPE, get_identifier ("__mf_cache"));
    mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
!   mf_cache_array_decl = mx_flag (mf_lookup_name (get_identifier ("__mf_lookup_cache")));
!   mf_cache_shift_decl = mx_flag (mf_lookup_name (get_identifier ("__mf_lc_shift")));
!   mf_cache_mask_decl = mx_flag (mf_lookup_name (get_identifier ("__mf_lc_mask")));
!   mf_check_fndecl = mf_lookup_name (get_identifier ("__mf_check"));
!   mf_register_fndecl = mf_lookup_name (get_identifier ("__mf_register"));
!   mf_unregister_fndecl = mf_lookup_name (get_identifier ("__mf_unregister"));
  
    done = 1;
  }
--- 136,154 ----
  static void
  mf_init_extern_trees ()
  {
    static int done = 0;
  
!   if (done) return;
  
!   mf_uintptr_type = TREE_TYPE (mflang_lookup_decl ("uintptr_t"));
!   mf_cache_array_decl = mx_flag (mflang_lookup_decl ("__mf_lookup_cache"));
!   mf_cache_struct_type = TREE_TYPE (TREE_TYPE (mf_cache_array_decl));
    mf_cache_structptr_type = build_pointer_type (mf_cache_struct_type);
!   mf_cache_shift_decl = mx_flag (mflang_lookup_decl ("__mf_lc_shift"));
!   mf_cache_mask_decl = mx_flag (mflang_lookup_decl ("__mf_lc_mask"));
!   mf_check_fndecl = mflang_lookup_decl ("__mf_check");
!   mf_register_fndecl = mflang_lookup_decl ("__mf_register");
!   mf_unregister_fndecl = mflang_lookup_decl ("__mf_unregister");
  
    done = 1;
  }
*************** mf_xform_decls (fnbody, fnparams)
*** 1187,1330 ****
  
  
  /* ------------------------------------------------------------------------ */
! /* global variable transform */
  
  /* A chain of EXPR_STMTs for calling __mf_register() at initialization
     time.  */
! static GTY (()) tree enqueued_call_stmt_chain = NULL_TREE;
  
  
! /* Build and enqueue EXPR_STMT for calling __mf_register on the object
!    given by the parameters.  One odd thing: the object's address is
!    given by the given assembler label string (since that's all we may
!    know about a string literal, or the static data thingie may be out
!    of the future scope).  To turn that into a validish C tree, we
!    create a weird synthetic VAR_DECL node.
! */ 
  
! static void
! mf_enqueue_register_call (label, regsize, regtype, regname)
!      const char* label;
!      tree regsize;
!      tree regtype;
!      tree regname;
  {
-   tree decltype, decl;
-   tree call_params;
    tree call_stmt;
  
!   mf_init_extern_trees ();
! 
!   /* See gcc-checker's c-bounds.c (declare_private_statics)  */
!   decltype = build_array_type (char_type_node, build_index_type (integer_zero_node));
!   decl = mx_flag (build_decl (VAR_DECL, get_identifier (label), decltype));
! 
!   TREE_STATIC (decl) = 1;
!   TREE_READONLY (decl) = 1;
!   TREE_ASM_WRITTEN (decl) = 1;
!   DECL_IGNORED_P (decl) = 1;
!   DECL_INITIAL (decl) = NULL_TREE;
!   layout_decl (decl, 0);
!   TREE_USED (decl) = 1;
!   SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
!   DECL_DEFER_OUTPUT (decl) = 1;
!   /* XXX: what else? */
!   /* rest_of_decl_compilation (decl, build_string (strlen (label) + 1, label), 1, 0); */
!   /* make_decl_rtl (decl,  build_string (strlen (label) + 1, label)); */
! 
!   call_params = tree_cons (NULL_TREE,
! 			   convert (mf_uintptr_type, 
! 				    mx_flag (build1 (ADDR_EXPR, 
! 						     build_pointer_type (TREE_TYPE (decl)),
! 						     decl))),
! 			   tree_cons (NULL_TREE, 
! 				      convert (mf_uintptr_type, regsize),
! 				      tree_cons (NULL_TREE,
! 						 regtype,
! 						 tree_cons (NULL_TREE,
! 							    regname,
! 							    NULL_TREE))));
! 
!   call_stmt = build1 (EXPR_STMT, void_type_node,
! 		      build_function_call (mf_register_fndecl,
! 					   call_params));
  
    /* Link this call into the chain. */
    TREE_CHAIN (call_stmt) = enqueued_call_stmt_chain;
    enqueued_call_stmt_chain = call_stmt;
  }
  
  
- /* Emit a synthetic CTOR function for the current file.  Populate it
-    from the enqueued __mf_register calls.  Call the RTL expanders
-    inline.  */
  
! static void
! mf_flush_enqueued_calls ()
  {
!   /* See profile.c (output_func_start_profiler) */
!   tree fnname;
!   char *nmplus;
!   tree fndecl;
!   tree body;
  
!   /* Short-circuit!  */
!   if (enqueued_call_stmt_chain == NULL_TREE)
!     return;
  
!   /* Create the COMPOUND_STMT that becomes the new function's body.  */
!   body = make_node (COMPOUND_STMT);
!   COMPOUND_BODY (body) = enqueued_call_stmt_chain;
!   enqueued_call_stmt_chain = NULL_TREE;
! 
!   /* Create a ctor function declaration.  */
!   nmplus = concat (IDENTIFIER_POINTER (get_file_function_name ('I')), "_mudflap", NULL);
!   fnname = get_identifier (nmplus);
!   free (nmplus);
!   fndecl = build_decl (FUNCTION_DECL, fnname,
! 		       build_function_type (void_type_node, NULL_TREE));
!   DECL_EXTERNAL (fndecl) = 0;
!   TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
!   TREE_USED (fndecl) = 1;
!   DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
! 
!   /* Now compile the sucker as we go.  This is a weird semi-inlined
!   form of the guts of the c-parse.y `fndef' production, and a hybrid
!   with c_expand_body. */
! 
!   /* start_function */
!   fndecl = pushdecl (fndecl);
!   pushlevel (0);
!   rest_of_decl_compilation (fndecl, 0, 1, 0);
!   announce_function (fndecl);
!   current_function_decl = fndecl;
!   DECL_INITIAL (fndecl) = error_mark_node;
!   DECL_SAVED_TREE (fndecl) = body;
!   make_decl_rtl (fndecl, NULL);
! 
!   /* store_parm_decls */
!   init_function_start (fndecl, input_filename, lineno);
!   cfun->x_whole_function_mode_p = 1;
! 
!   /* finish_function */
!   poplevel (1, 0, 1);
!   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
! 
!   /* c_expand_body */
!   expand_function_start (fndecl, 0);
!   expand_stmt (DECL_SAVED_TREE (fndecl));
!   if (lang_expand_function_end)
!     (*lang_expand_function_end) ();
!   expand_function_end (input_filename, lineno, 0);
!   rest_of_compilation (fndecl);
!   if (! quiet_flag) 
!     fflush (asm_out_file);
!   current_function_decl = NULL_TREE;
!   if (targetm.have_ctors_dtors)
!     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
!                                      DEFAULT_INIT_PRIORITY);
!   else
!     static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
  }
  
  
--- 1049,1193 ----
  
  
  /* ------------------------------------------------------------------------ */
! 
! 
! /* Remember given node as a static of some kind: global data,
!    function-scope static, or an anonymous constant.  Its assembler
!    label is given.
! */
! 
! 
! /* A list of globals whose incomplete declarations we encountered.
!    Instead of emitting the __mf_register call for them here, it's
!    delayed until program finish time.  If they're still incomplete by
!    then, warnings are emitted.  */
! 
! static GTY (()) varray_type deferred_static_decls;
! static GTY (()) varray_type deferred_static_decl_labels;
! static int deferred_static_decls_init;
! 
! /* What I really want is a std::map<union tree_node,std::string> .. :-(  */
  
  /* A chain of EXPR_STMTs for calling __mf_register() at initialization
     time.  */
! static GTY (()) tree enqueued_call_stmt_chain;
  
  
! void 
! mudflap_enqueue_decl (obj, label)
!      tree obj;
!      const char *label;
! {
!   if (TREE_MUDFLAPPED_P (obj))
!     return;
  
!   /*
!   fprintf (stderr, "enqueue_decl obj=`");
!   print_generic_expr (stderr, obj, 0);
!   fprintf (stderr, "' label=`%s'\n", label);
!   */
! 
!   if (COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (obj))) 
!     {
!       /* NB: the above condition doesn't require TREE_USED or
!          TREE_ADDRESSABLE.  That's because this object may be a global
!          only used from other compilation units.  XXX: Maybe static
!          objects could require those attributes being set.  */
!       tree call_stmt =
! 	mflang_register_call (label,
! 			      size_in_bytes (TREE_TYPE (obj)),
! 			      build_int_2 (3, 0), /* __MF_TYPE_STATIC */
! 			      mf_varname_tree (obj));
! 
!       /* Link this call into the chain. */
!       TREE_CHAIN (call_stmt) = enqueued_call_stmt_chain;
!       enqueued_call_stmt_chain = call_stmt;
!     }
!   else
!     {
!       unsigned i;
!       int found_p;
!       
!       if (! deferred_static_decls_init)
! 	{
! 	  deferred_static_decls_init = 1;
! 	  VARRAY_TREE_INIT (deferred_static_decls, 10, "deferred static list");
! 	  VARRAY_CHAR_PTR_INIT (deferred_static_decl_labels, 10, "label list");
! 	}
!       
!       /* Ugh, linear search... */
!       found_p = 0;
!       for (i=0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
! 	if (VARRAY_TREE (deferred_static_decls, i) == obj)
! 	  found_p = 1;
!       
!       if (found_p)
! 	warning_with_decl (obj, "mudflap cannot track lifetime of `%s'", 
! 			   IDENTIFIER_POINTER (DECL_NAME (obj)));
!       else
! 	{
! 	  VARRAY_PUSH_TREE (deferred_static_decls, obj);
! 	  VARRAY_PUSH_CHAR_PTR (deferred_static_decl_labels, (char *) label);
! 	}
!     }
! }
! 
! 
! void 
! mudflap_enqueue_constant (obj, label)
!      tree obj;
!      const char *label;
  {
    tree call_stmt;
  
!   if (TREE_MUDFLAPPED_P (obj))
!     return;
  
+   call_stmt =
+     (TREE_CODE (obj) == STRING_CST)
+     ? mflang_register_call (label,
+ 			    build_int_2 (TREE_STRING_LENGTH (obj), 0),
+ 			    build_int_2 (3, 0), /* __MF_TYPE_STATIC */
+ 			    mx_flag (fix_string_type
+ 				     (build_string (15, "string literal"))))
+     : mflang_register_call (label,
+ 			    size_in_bytes (TREE_TYPE (obj)),
+ 			    build_int_2 (3, 0), /* __MF_TYPE_STATIC */
+ 			    mx_flag (fix_string_type
+ 				     (build_string (9, "constant"))));
+     
    /* Link this call into the chain. */
    TREE_CHAIN (call_stmt) = enqueued_call_stmt_chain;
    enqueued_call_stmt_chain = call_stmt;
  }
  
  
  
! /* Emit any file-wide instrumentation.  */
! void 
! mudflap_finish_file ()
  {
!   /* Try to give the deferred objects one final try.  */
!   if (deferred_static_decls_init)
!     {
!       unsigned i;
  
!       for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
! 	{
! 	  tree obj = VARRAY_TREE (deferred_static_decls, i);
! 	  const char *label = VARRAY_CHAR_PTR (deferred_static_decl_labels, i);
  
! 	  /* Call enqueue_decl again on the same object it has previously
! 	     put into the table.  (It won't modify the table this time, so
! 	     infinite iteration is not a problem.)  */
! 	  mudflap_enqueue_decl (obj, label);
! 	}
! 
!       VARRAY_CLEAR (deferred_static_decls);
!       VARRAY_CLEAR (deferred_static_decl_labels);
!     }
! 	     
!   mflang_flush_calls (enqueued_call_stmt_chain);
  }
  
  
Index: tree-mudflap.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.h,v
retrieving revision 1.1.2.2
diff -c -p -r1.1.2.2 tree-mudflap.h
*** tree-mudflap.h	20 Aug 2002 19:21:40 -0000	1.1.2.2
--- tree-mudflap.h	13 Jan 2003 23:04:33 -0000
***************
*** 1,5 ****
  /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
!    Copyright (C) 2001, 2002 Free Software Foundation, Inc.
     Contributed by Frank Ch. Eigler <fche@redhat.com>
  
  This file is part of GCC.
--- 1,5 ----
  /* Mudflap: narrow-pointer bounds-checking by tree rewriting.
!    Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
     Contributed by Frank Ch. Eigler <fche@redhat.com>
  
  This file is part of GCC.
*************** extern void mudflap_c_function PARAMS ((
*** 26,30 ****
--- 26,36 ----
  extern void mudflap_enqueue_decl PARAMS ((tree, const char *));
  extern void mudflap_enqueue_constant PARAMS ((tree, const char *));
  extern void mudflap_finish_file PARAMS ((void));
+ 
+ /* To be provided by a front-end interface module. */
+ extern tree mflang_lookup_decl PARAMS ((const char *));
+ extern tree mflang_register_call PARAMS ((const char*, tree, tree, tree));
+ extern void mflang_flush_calls PARAMS ((tree));
+ 
  
  #endif /* TREE_MUDFLAP_H */
Index: tree-nomudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-nomudflap.c,v
retrieving revision 1.1.2.4
diff -c -p -r1.1.2.4 tree-nomudflap.c
*** tree-nomudflap.c	3 Dec 2002 22:54:34 -0000	1.1.2.4
--- tree-nomudflap.c	13 Jan 2003 23:04:33 -0000
*************** mudflap_enqueue_decl (obj, label)
*** 58,64 ****
       tree obj ATTRIBUTE_UNUSED;
       const char *label ATTRIBUTE_UNUSED;
  {
!   abort ();
  }
  
  
--- 58,64 ----
       tree obj ATTRIBUTE_UNUSED;
       const char *label ATTRIBUTE_UNUSED;
  {
!   internal_error ("mudflap: this language is not supported");
  }
  
  
*************** mudflap_enqueue_constant (obj, label)
*** 67,73 ****
       tree obj ATTRIBUTE_UNUSED;
       const char *label ATTRIBUTE_UNUSED;
  {
!   abort ();
  }
  
  
--- 67,73 ----
       tree obj ATTRIBUTE_UNUSED;
       const char *label ATTRIBUTE_UNUSED;
  {
!   internal_error ("mudflap: this language is not supported");
  }
  
  
*************** mudflap_enqueue_constant (obj, label)
*** 77,83 ****
  void 
  mudflap_finish_file ()
  {
!   abort ();
  }
  
  
--- 77,83 ----
  void 
  mudflap_finish_file ()
  {
!   internal_error ("mudflap: this language is not supported");
  }
  
  
Index: cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v
retrieving revision 1.115.2.19
diff -c -p -r1.115.2.19 Make-lang.in
*** cp/Make-lang.in	3 Jan 2003 01:57:28 -0000	1.115.2.19
--- cp/Make-lang.in	13 Jan 2003 23:04:34 -0000
*************** CXX_OBJS = cp/call.o cp/decl.o cp/expr.o
*** 87,93 ****
   cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \
   cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
   cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o \
!  cp/optimize.o cp/mangle.o cp/cp-lang.o cp/cp-simplify.o
  
  # Use loose warnings for this front end.
  cp-warn =
--- 87,94 ----
   cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \
   cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
   cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o \
!  cp/optimize.o cp/mangle.o cp/cp-lang.o cp/cp-simplify.o \
!  tree-mudflap.o cp/cp-mudflap.o
  
  # Use loose warnings for this front end.
  cp-warn =
*************** cp/parse.o: cp/parse.c $(CXX_TREE_H) $(T
*** 277,282 ****
--- 278,285 ----
  	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
  		$(srcdir)/cp/parse.c $(OUTPUT_OPTION)
  cp/cp-simplify.o: cp/cp-simplify.c $(CXX_TREE_H) toplev.h c-common.h \
+ 	$(TM_H) coretypes.h
+ cp/cp-mudflap.o: cp/cp-mudflap.c $(CXX_TREE_H) toplev.h c-common.h \
  	$(TM_H) coretypes.h
  
  #
Index: cp/cp-mudflap.c
===================================================================
RCS file: cp/cp-mudflap.c
diff -N cp/cp-mudflap.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- cp/cp-mudflap.c	13 Jan 2003 23:04:34 -0000
***************
*** 0 ****
--- 1,218 ----
+ /* Mudflap: narrow-pointer bounds-checking by tree rewriting: 
+    C++ front-end interface.
+ 
+    Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+    Contributed by Frank Ch. Eigler <fche@redhat.com>
+    and Graydon Hoare <graydon@redhat.com>
+ 
+ This file is part of GCC.
+ 
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ for more details.
+ 
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING.  If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ 
+ #include "config.h"
+ #include "errors.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "tree-inline.h"
+ #include "cp-tree.h"
+ #include "c-common.h"
+ #include "diagnostic.h"
+ #include "output.h"
+ #include "varray.h"
+ #include "tree-mudflap.h"
+ #include "target.h"
+ #include "flags.h"
+ #include "rtl.h"
+ #include "toplev.h"
+ 
+ 
+ 
+ /* ------------------------------------------------------------------------ */
+ 
+ static tree mx_flag PARAMS ((tree));
+ 
+ /* XXX: copied from tree-mudflap.c */
+ static tree
+ mx_flag (t)
+      tree t;
+ {
+   if (!t)
+     abort ();
+ #define MARK_TREE_MUDFLAPPED(tree)  do { TREE_BOUNDED (tree) = 1; } while (0)
+   MARK_TREE_MUDFLAPPED(t);
+   return t;
+ }
+ 
+ 
+ 
+ /* ------------------------------------------------------------------------ */
+ 
+ 
+ 
+ /* Initialize the global tree nodes that correspond to mf-runtime.h
+    declarations.  */
+ tree
+ mflang_lookup_decl (name)
+      const char* name;
+ {
+   tree decl = lookup_name (get_identifier (name), 1);
+   if (decl == NULL_TREE)
+     internal_error ("mudflap: cannot find declaration of `%s' from mf-runtime.h", 
+ 		    name);
+ 
+   return decl;
+ }
+ 
+ 
+ 
+ /* Build and return EXPR_STMT for calling __mf_register on the object
+    given by the parameters.  One odd thing: the object's address is
+    given by the given assembler label string (since that's all we may
+    know about a string literal, or the static data thingie may be out
+    of the future scope).  To turn that into a validish C tree, we
+    create a weird synthetic VAR_DECL node.
+ */ 
+ 
+ tree
+ mflang_register_call (label, regsize, regtype, regname)
+      const char* label;
+      tree regsize;
+      tree regtype;
+      tree regname;
+ {
+   tree decltype, decl;
+   tree call_params;
+   tree call_stmt;
+ 
+   /* XXX: would be nicer not to duplicate these. */
+   tree mf_uintptr_type = TREE_TYPE (mflang_lookup_decl ("uintptr_t"));
+   tree mf_register_fndecl = mflang_lookup_decl ("__mf_register");
+ 
+   /* See gcc-checker's c-bounds.c (declare_private_statics)  */
+   decltype = build_array_type (char_type_node, build_index_type (integer_zero_node));
+   decl = mx_flag (build_decl (VAR_DECL, get_identifier (label), decltype));
+ 
+   TREE_STATIC (decl) = 1;
+   TREE_READONLY (decl) = 1;
+   TREE_ASM_WRITTEN (decl) = 1;
+   DECL_IGNORED_P (decl) = 1;
+   DECL_INITIAL (decl) = NULL_TREE;
+   layout_decl (decl, 0);
+   TREE_USED (decl) = 1;
+   SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
+   DECL_DEFER_OUTPUT (decl) = 1;
+   /* XXX: what else? */
+   /* rest_of_decl_compilation (decl, build_string (strlen (label) + 1, label), 1, 0); */
+   /* make_decl_rtl (decl,  build_string (strlen (label) + 1, label)); */
+ 
+   call_params = tree_cons (NULL_TREE,
+ 			   convert (mf_uintptr_type, 
+ 				    mx_flag (build1 (ADDR_EXPR, 
+ 						     build_pointer_type (TREE_TYPE (decl)),
+ 						     decl))),
+ 			   tree_cons (NULL_TREE, 
+ 				      convert (mf_uintptr_type, regsize),
+ 				      tree_cons (NULL_TREE,
+ 						 regtype,
+ 						 tree_cons (NULL_TREE,
+ 							    regname,
+ 							    NULL_TREE))));
+ 
+   call_stmt = build1 (EXPR_STMT, void_type_node,
+ 		      build_function_call (mf_register_fndecl,
+ 					   call_params));
+ 
+   return call_stmt;
+ }
+ 
+ 
+ 
+ /* Emit a synthetic CTOR function for the current file.  Populate it
+    from the enqueued __mf_register calls.  Call the RTL expanders
+    inline.  */
+ 
+ void
+ mflang_flush_calls (enqueued_call_stmt_chain)
+      tree enqueued_call_stmt_chain;
+ {
+   /* See profile.c (output_func_start_profiler) */
+   tree fnname;
+   char *nmplus;
+   tree fndecl;
+   tree body;
+ 
+   /* Short-circuit!  */
+   if (enqueued_call_stmt_chain == NULL_TREE)
+     return;
+ 
+   /* Create the COMPOUND_STMT that becomes the new function's body.  */
+   body = make_node (COMPOUND_STMT);
+   COMPOUND_BODY (body) = enqueued_call_stmt_chain;
+   enqueued_call_stmt_chain = NULL_TREE;
+ 
+   /* Create a ctor function declaration.  */
+   nmplus = concat (IDENTIFIER_POINTER (get_file_function_name ('I')), "_mudflap", NULL);
+   fnname = get_identifier (nmplus);
+   free (nmplus);
+   fndecl = build_decl (FUNCTION_DECL, fnname,
+ 		       build_function_type (void_type_node, NULL_TREE));
+   DECL_EXTERNAL (fndecl) = 0;
+   TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
+   TREE_USED (fndecl) = 1;
+   DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ 
+   /* Now compile the sucker as we go.  This is a weird semi-inlined
+   form of the guts of the c-parse.y `fndef' production, and a hybrid
+   with c_expand_body. */
+ 
+   /* start_function */
+   fndecl = pushdecl (fndecl);
+   pushlevel (0);
+   rest_of_decl_compilation (fndecl, 0, 1, 0);
+   announce_function (fndecl);
+   current_function_decl = fndecl;
+   DECL_INITIAL (fndecl) = error_mark_node;
+   DECL_SAVED_TREE (fndecl) = body;
+   make_decl_rtl (fndecl, NULL);
+ 
+   /* store_parm_decls */
+   init_function_start (fndecl, input_filename, lineno);
+   cfun->x_whole_function_mode_p = 1;
+ 
+   /* finish_function */
+   poplevel (1, 0, 1);
+   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ 
+   /* c_expand_body */
+   expand_function_start (fndecl, 0);
+   expand_stmt (DECL_SAVED_TREE (fndecl));
+   if (lang_expand_function_end)
+     (*lang_expand_function_end) ();
+   expand_function_end (input_filename, lineno, 0);
+   rest_of_compilation (fndecl);
+   if (! quiet_flag) 
+     fflush (asm_out_file);
+   current_function_decl = NULL_TREE;
+ 
+   if (targetm.have_ctors_dtors)
+     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
+                                      DEFAULT_INIT_PRIORITY);
+   else
+     static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
+ }
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.540.2.20
diff -c -p -r1.540.2.20 decl2.c
*** cp/decl2.c	3 Jan 2003 01:57:34 -0000	1.540.2.20
--- cp/decl2.c	13 Jan 2003 23:04:34 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 47,52 ****
--- 47,54 ----
  #include "cpplib.h"
  #include "target.h"
  #include "c-common.h"
+ #include "tree-mudflap.h"
+ 
  extern cpp_reader *parse_in;
  
  /* This structure contains information about the initializations
*************** finish_file ()
*** 2714,2719 ****
--- 2716,2725 ----
    timevar_push (TV_VARCONST);
  
    emit_support_tinfos ();
+ 
+   /* Emit mudflap static registration function.  */
+   if (flag_mudflap)
+     mudflap_finish_file ();
    
    do 
      {
Index: cp/optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v
retrieving revision 1.81.10.11
diff -c -p -r1.81.10.11 optimize.c
*** cp/optimize.c	3 Jan 2003 01:57:36 -0000	1.81.10.11
--- cp/optimize.c	13 Jan 2003 23:04:34 -0000
*************** Software Foundation, 59 Temple Place - S
*** 36,41 ****
--- 36,42 ----
  #include "hashtab.h"
  #include "debug.h"
  #include "tree-inline.h"
+ #include "tree-mudflap.h"
  #include "flags.h"
  #include "langhooks.h"
  #include "diagnostic.h"
*************** optimize_function (tree fn)
*** 84,89 ****
--- 85,100 ----
      {
        /* Debugging dump after simplification.  */
        dump_function (TDI_simple, fn);
+ 
+       if (flag_mudflap)
+ 	{
+ 	  mudflap_c_function (fn);
+ 
+ 	  /* Simplify mudflap instrumentation.  FIXME  Long term: Would it
+ 	     be better for mudflap to simplify each tree as it generates
+ 	     them?  */
+ 	  simplify_function_tree (fn);
+ 	}
  
        /* Invoke the SSA tree optimizer.  */
        if (optimize >= 1 && 0)



More information about the Gcc-patches mailing list