Patch for -fcheck-memory-usage and -fprefix-function-name

Tristan Gingold gingold@email.enst.fr
Wed Aug 26 04:53:00 GMT 1998


Hello

  Here is a patch that fixes a few bugs with -fcheck-memory-usage,
  and allows -fprefix-function-name to work with constructor and with g++.

  I took the liberty to change the interface of assemble_{con,de}structor;
  please tell me if this was not a good idea.

Thanks.

  Tristan.

egcs-19980803.orig/gcc/ChangeLog
Mon Jul  6 14:04:23 1998  Tristan Gingold  <gingold@zenobie.enst.fr>

	* invoke.texi (Code Gen Options): -fcheck-memory-usage updated.
	* expr.c (expand_expr): In VAR_DECL case, check even static
	variable, because memory can become uninitialized (thanks to
	Ken Raeburn).
	* expr.c (store_constructor): Insert a call to chkr_set_right
	if -fcheck-memory-usage, because memory was initialized.
	* expr.c (store_expr): Do not copy bitmap if the initialisation is
	done with a constructor.

Tue Aug 25 16:11:27 1998  Tristan Gingold  <gingold@email.enst.fr>

	* varasm.c (assemble_destructor, assemble_constructor): The argument
	is now a DECL tree. The name is got from DECL_RTL.
	* output.h: Prototypes of assemble_destructor and assemble_constructor
	changed.
	* c-lang.c (finish_file): Calls to assemble_constructor and
	assemble_desctructor changed.
	* c-decl.c (finish_function): Likewise.
	* profile.c (output_func_start_profiler): Likewise.
	* c-decl.c (duplicate_decls): Copy the assembler_name.
	* dbxout.c (dbxout_symbol): Use the name but not the assembler as
	function name for stabs.
	* varasm.c (make_function_rtl): If -fprefix-function-name, do not
	add the prefix if the assembler name is set by the user.
	* varasm.c (make_decl_rtl): Ditto.

egcs-19980803/gcc/cp/ChangeLog
1998-08-25  Tristan Gingold  <gingold@email.enst.fr>

	* decl2.c (finish_objects): Calls to assemble_constructor and
	assemble_desctructor changed, to be compliant to the new arguement
 	type.

diff -rcp egcs-19980803.orig/gcc/c-decl.c egcs-19980803/gcc/c-decl.c
*** egcs-19980803.orig/gcc/c-decl.c	Wed Jul  8 14:15:56 1998
--- egcs-19980803/gcc/c-decl.c	Wed Aug 26 13:24:34 1998
*************** duplicate_decls (newdecl, olddecl, diffe
*** 1927,1932 ****
--- 1927,1936 ----
        if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
  	DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
  
+       /* Copy the assembler name.
+ 	 Currently, it can only be defined in the prototype.  */
+       DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl);
+ 
        if (TREE_CODE (newdecl) == FUNCTION_DECL)
  	{
  	  DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
*************** finish_decl (decl, init, asmspec_tree)
*** 4001,4007 ****
  	DECL_BUILT_IN (decl) = 0;
  	DECL_RTL (decl) = 0;
        }
- 
    /* Output the assembler code and/or RTL code for variables and functions,
       unless the type is an undefined structure or union.
       If not, it will get done when the type is completed.  */
--- 4005,4010 ----
*************** finish_function (nested)
*** 7245,7251 ****
  	static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors);
        else
  #endif
!       assemble_constructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
      }
    if (DECL_STATIC_DESTRUCTOR (fndecl))
      {
--- 7248,7254 ----
  	static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors);
        else
  #endif
! 	assemble_constructor (fndecl);
      }
    if (DECL_STATIC_DESTRUCTOR (fndecl))
      {
*************** finish_function (nested)
*** 7254,7260 ****
  	static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors);
        else
  #endif
!       assemble_destructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
      }
  
    if (! nested)
--- 7257,7263 ----
  	static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors);
        else
  #endif
! 	assemble_destructor (fndecl);
      }
  
    if (! nested)
diff -rcp egcs-19980803.orig/gcc/c-lang.c egcs-19980803/gcc/c-lang.c
*** egcs-19980803.orig/gcc/c-lang.c	Fri Jun 19 23:58:00 1998
--- egcs-19980803/gcc/c-lang.c	Tue Aug 25 15:57:35 1998
*************** finish_file ()
*** 163,169 ****
  		      build_parse_node (CALL_EXPR, fnname, void_list_node,
  					NULL_TREE),
  		      NULL_TREE, NULL_TREE, 0);
-       fnname = DECL_ASSEMBLER_NAME (current_function_decl);
        store_parm_decls ();
  
        for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
--- 163,168 ----
*************** finish_file ()
*** 172,178 ****
  
        finish_function (0);
  
!       assemble_constructor (IDENTIFIER_POINTER (fnname));
      }
  #endif
  #ifndef ASM_OUTPUT_DESTRUCTOR
--- 171,177 ----
  
        finish_function (0);
  
!       assemble_constructor (current_function_decl);
      }
  #endif
  #ifndef ASM_OUTPUT_DESTRUCTOR
*************** finish_file ()
*** 183,189 ****
  		      build_parse_node (CALL_EXPR, fnname, void_list_node,
  					NULL_TREE),
  		      NULL_TREE, NULL_TREE, 0);
-       fnname = DECL_ASSEMBLER_NAME (current_function_decl);
        store_parm_decls ();
  
        for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
--- 182,187 ----
*************** finish_file ()
*** 192,198 ****
  
        finish_function (0);
  
!       assemble_destructor (IDENTIFIER_POINTER (fnname));
      }
  #endif
  }
--- 190,196 ----
  
        finish_function (0);
  
!       assemble_destructor (current_function_decl);
      }
  #endif
  }

diff -rcp egcs-19980803.orig/gcc/cp/decl2.c egcs-19980803/gcc/cp/decl2.c
*** egcs-19980803.orig/gcc/cp/decl2.c	Mon Jul 27 13:15:03 1998
--- egcs-19980803/gcc/cp/decl2.c	Tue Aug 25 15:56:58 1998
*************** static void
*** 2957,2964 ****
  finish_objects (method_type)
       int method_type;
  {
-   char *fnname;
- 
    tree list = (method_type == 'I' ? static_ctors : static_dtors);
  
    if (! current_function_decl && list)
--- 2957,2962 ----
*************** finish_objects (method_type)
*** 2970,2977 ****
    if (! current_function_decl)
      return;
  
-   fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
- 
    /* Finish up. */
    expand_end_bindings (getdecls (), 1, 0);
    poplevel (1, 0, 0);
--- 2968,2973 ----
*************** finish_objects (method_type)
*** 2979,2987 ****
    finish_function (lineno, 0, 0);
  
    if (method_type == 'I')
!     assemble_constructor (fnname);
    else
!     assemble_destructor (fnname);
  }
  
  /* Generate a function to run a set of global destructors.  Subroutine of
--- 2975,2983 ----
    finish_function (lineno, 0, 0);
  
    if (method_type == 'I')
!     assemble_constructor (current_function_decl);
    else
!     assemble_destructor (current_function_decl);
  }
  
  /* Generate a function to run a set of global destructors.  Subroutine of
diff -rcp egcs-19980803.orig/gcc/dbxout.c egcs-19980803/gcc/dbxout.c
*** egcs-19980803.orig/gcc/dbxout.c	Fri Jul 24 02:31:23 1998
--- egcs-19980803/gcc/dbxout.c	Thu Aug 20 16:33:41 1998
*************** dbxout_symbol (decl, local)
*** 1719,1725 ****
        FORCE_TEXT;
  
        fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
! 	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
  	       TREE_PUBLIC (decl) ? 'F' : 'f');
  
        current_sym_code = N_FUN;
--- 1719,1725 ----
        FORCE_TEXT;
  
        fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
! 	       IDENTIFIER_POINTER (DECL_NAME (decl)),
  	       TREE_PUBLIC (decl) ? 'F' : 'f');
  
        current_sym_code = N_FUN;
diff -rcp egcs-19980803.orig/gcc/expr.c egcs-19980803/gcc/expr.c
*** egcs-19980803.orig/gcc/expr.c	Mon Jul 13 11:26:59 1998
--- egcs-19980803/gcc/expr.c	Thu Aug 20 16:33:41 1998
*************** store_expr (exp, target, want_value)
*** 3439,3445 ****
  
    if (flag_check_memory_usage
        && GET_CODE (target) == MEM
!       && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
      {
        if (GET_CODE (temp) == MEM)
          emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
--- 3439,3446 ----
  
    if (flag_check_memory_usage
        && GET_CODE (target) == MEM
!       && AGGREGATE_TYPE_P (TREE_TYPE (exp))
!       && TREE_CODE (exp) != CONSTRUCTOR)
      {
        if (GET_CODE (temp) == MEM)
          emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
*************** store_constructor (exp, target, cleared)
*** 3853,3858 ****
--- 3854,3866 ----
  	  store_constructor_field (to_rtx, bitsize, bitpos,
  				   mode, TREE_VALUE (elt), type, cleared);
  	}
+ 
+       if (flag_check_memory_usage && GET_CODE (target) == MEM)
+ 	emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ 			   XEXP (target, 0), ptr_mode,
+ 			   expr_size(exp), TYPE_MODE (sizetype),
+ 			   GEN_INT (MEMORY_USE_RW),
+ 			   TYPE_MODE (integer_type_node));
      }
    else if (TREE_CODE (type) == ARRAY_TYPE)
      {
*************** store_constructor (exp, target, cleared)
*** 4056,4066 ****
--- 4064,4081 ----
  				       mode, value, type, cleared);
  	    }
  	}
+       if (flag_check_memory_usage && GET_CODE (target) == MEM)
+ 	emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ 			   XEXP (target, 0), ptr_mode,
+ 			   expr_size(exp), TYPE_MODE (sizetype),
+ 			   GEN_INT (MEMORY_USE_RW),
+ 			   TYPE_MODE (integer_type_node));
      }
    /* set constructor assignments */
    else if (TREE_CODE (type) == SET_TYPE)
      {
        tree elt = CONSTRUCTOR_ELTS (exp);
+       rtx xtarget = XEXP (target, 0); /* rnielsen */
        int nbytes = int_size_in_bytes (type), nbits;
        tree domain = TYPE_DOMAIN (type);
        tree domain_min, domain_max, bitlength;
*************** store_constructor (exp, target, cleared)
*** 4081,4086 ****
--- 4096,4107 ----
  	  if (!cleared)
  	    clear_storage (target, expr_size (exp),
  			   TYPE_ALIGN (type) / BITS_PER_UNIT);
+ 	  if (flag_check_memory_usage && GET_CODE (target) == MEM)
+ 	    emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ 			       target, ptr_mode,
+ 			       expr_size(exp), TYPE_MODE (sizetype),
+ 			       GEN_INT (MEMORY_USE_RW),
+ 			       TYPE_MODE (integer_type_node));
  	  return;
  	}
  
*************** store_constructor (exp, target, cleared)
*** 4235,4240 ****
--- 4256,4267 ----
  	  if (REG_P (target))
  	    emit_move_insn (target, targetx);
  	}
+       if (flag_check_memory_usage && GET_CODE (target) == MEM)
+ 	emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ 			   xtarget, ptr_mode,
+ 			   expr_size(exp), TYPE_MODE (sizetype),
+ 			   GEN_INT (MEMORY_USE_RW),
+ 			   TYPE_MODE (integer_type_node));
      }
  
    else
*************** get_memory_usage_from_modifier (modifier
*** 4652,4658 ****
     This is done by generating instructions to perform the arithmetic
     and returning a pseudo-register containing the value.
  
!    The returned value may be a REG, SUBREG, MEM or constant.  */
  
  rtx
  force_operand (value, target)
--- 4679,4685 ----
     This is done by generating instructions to perform the arithmetic
     and returning a pseudo-register containing the value.
  
!    The returd value may be a REG, SUBREG, MEM or constant.  */
  
  rtx
  force_operand (value, target)
*************** expand_expr (exp, target, tmode, modifie
*** 5312,5319 ****
           Aggregates are not checked.  */
        if (flag_check_memory_usage && code == VAR_DECL
  	  && GET_CODE (DECL_RTL (exp)) == MEM
- 	  && DECL_CONTEXT (exp) != NULL_TREE
- 	  && ! TREE_STATIC (exp)
  	  && ! AGGREGATE_TYPE_P (TREE_TYPE (exp)))
  	{
  	  enum memory_use_mode memory_usage;
--- 5339,5344 ----
diff -rcp egcs-19980803.orig/gcc/invoke.texi egcs-19980803/gcc/invoke.texi
*** egcs-19980803.orig/gcc/invoke.texi	Mon Jul 13 14:39:33 1998
--- egcs-19980803/gcc/invoke.texi	Thu Aug 20 16:33:42 1998
*************** the offsets of structure members won't a
*** 5862,5869 ****
  @item -fcheck-memory-usage
  Generate extra code to check each memory access.  GNU CC will generate
  code that is suitable for a detector of bad memory accesses such as
! @file{Checker}.  If you specify this option, you can not use the
! @code{asm} or @code{__asm__} keywords.
  
  You must also specify this option when you compile functions you call that
  have side effects.  If you do not, you may get erroneous messages from
--- 5862,5871 ----
  @item -fcheck-memory-usage
  Generate extra code to check each memory access.  GNU CC will generate
  code that is suitable for a detector of bad memory accesses such as
! @file{Checker}.  Do not expect to use this feature without such a tools:
! the code produced need a separated package to be linked with.
! If you specify this option, you can not use the @code{asm} or
! @code{__asm__} keywords.
  
  You must also specify this option when you compile functions you call that
  have side effects.  If you do not, you may get erroneous messages from
diff -rcp egcs-19980803.orig/gcc/output.h egcs-19980803/gcc/output.h
*** egcs-19980803.orig/gcc/output.h	Mon Jun  8 20:30:18 1998
--- egcs-19980803/gcc/output.h	Tue Aug 25 15:58:22 1998
*************** extern void assemble_asm		PROTO((tree));
*** 210,221 ****
     How this is done depends on what sort of assembler and linker
     are in use.
  
!    NAME should be the name of a global function to be called
!    at exit time.  This name is output using assemble_name.  */
! extern void assemble_destructor		PROTO((char *));
  
  /* Likewise for global constructors.  */
! extern void assemble_constructor	PROTO((char *));
  
  /* Likewise for entries we want to record for garbage collection.
     Garbage collection is still under development.  */
--- 210,221 ----
     How this is done depends on what sort of assembler and linker
     are in use.
  
!    FNDECL should be a DECL tree of a glocal function to be called
!    at exit time.  This name is output using DECL_RTL.  */
! extern void assemble_destructor		PROTO((tree));
  
  /* Likewise for global constructors.  */
! extern void assemble_constructor	PROTO((tree));
  
  /* Likewise for entries we want to record for garbage collection.
     Garbage collection is still under development.  */
diff -rcp egcs-19980803.orig/gcc/profile.c egcs-19980803/gcc/profile.c
*** egcs-19980803.orig/gcc/profile.c	Wed Jul 22 20:49:53 1998
--- egcs-19980803/gcc/profile.c	Tue Aug 25 15:56:10 1998
*************** output_func_start_profiler ()
*** 1698,1702 ****
      fflush (asm_out_file);
    current_function_decl = NULL_TREE;
  
!   assemble_constructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
  }
--- 1698,1702 ----
      fflush (asm_out_file);
    current_function_decl = NULL_TREE;
  
!   assemble_constructor (fndecl);
  }
diff -rcp egcs-19980803.orig/gcc/varasm.c egcs-19980803/gcc/varasm.c
*** egcs-19980803.orig/gcc/varasm.c	Tue Jul  7 00:40:02 1998
--- egcs-19980803/gcc/varasm.c	Wed Aug 26 13:31:03 1998
*************** make_function_rtl (decl)
*** 511,517 ****
           prefixed.  Even static functions are prefixed because they
           could be declared latter.  Note that a nested function name
           is not prefixed.  */
!       if (flag_prefix_function_name)
          {
            new_name = (char *) alloca (strlen (name) + CHKR_PREFIX_SIZE + 1);
            strcpy (new_name, CHKR_PREFIX);
--- 511,517 ----
           prefixed.  Even static functions are prefixed because they
           could be declared latter.  Note that a nested function name
           is not prefixed.  */
!       if (flag_prefix_function_name && *name != '*')
          {
            new_name = (char *) alloca (strlen (name) + CHKR_PREFIX_SIZE + 1);
            strcpy (new_name, CHKR_PREFIX);
*************** make_decl_rtl (decl, asmspec, top_level)
*** 752,758 ****
  	  /* When -fprefix-function-name is used, the functions
  	     names are prefixed.  Only nested function names are not
  	     prefixed.  */
! 	  if (flag_prefix_function_name && TREE_CODE (decl) == FUNCTION_DECL)
  	    {
  	      char *new_name;
  	      new_name = (char *) alloca (strlen (name) + CHKR_PREFIX_SIZE 
--- 752,759 ----
  	  /* When -fprefix-function-name is used, the functions
  	     names are prefixed.  Only nested function names are not
  	     prefixed.  */
! 	  if (flag_prefix_function_name && TREE_CODE (decl) == FUNCTION_DECL
! 	      && !asmspec)
  	    {
  	      char *new_name;
  	      new_name = (char *) alloca (strlen (name) + CHKR_PREFIX_SIZE 
*************** assemble_asm (string)
*** 878,890 ****
     How this is done depends on what sort of assembler and linker
     are in use.
  
!    NAME should be the name of a global function to be called
!    at exit time.  This name is output using assemble_name.  */
  
  void
! assemble_destructor (name)
!      char *name;
  {
  #ifdef ASM_OUTPUT_DESTRUCTOR
    ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);
  #else
--- 879,893 ----
     How this is done depends on what sort of assembler and linker
     are in use.
  
!    FNDECL should be a DECL tree of a glocal function to be called
!    at exit time.  This name is output using DECL_RTL.  */
  
  void
! assemble_destructor (fndecl)
!      tree fndecl;
  {
+   char *name = XSTR (XEXP (DECL_RTL (fndecl), 0), 0);
+ 
  #ifdef ASM_OUTPUT_DESTRUCTOR
    ASM_OUTPUT_DESTRUCTOR (asm_out_file, name);
  #else
*************** assemble_destructor (name)
*** 902,910 ****
  /* Likewise for global constructors.  */
  
  void
! assemble_constructor (name)
!      char *name;
  {
  #ifdef ASM_OUTPUT_CONSTRUCTOR
    ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);
  #else
--- 905,915 ----
  /* Likewise for global constructors.  */
  
  void
! assemble_constructor (fndecl)
!      tree fndecl;
  {
+   char *name = XSTR (XEXP (DECL_RTL (fndecl), 0), 0);
+ 
  #ifdef ASM_OUTPUT_CONSTRUCTOR
    ASM_OUTPUT_CONSTRUCTOR (asm_out_file, name);
  #else



More information about the Gcc-patches mailing list