This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH to avoid copying tail padding (was: GCC 3.2)


On Fri, 02 Aug 2002 12:57:19 +0100, Jason Merrill <jason@redhat.com> wrote:

> Here's the patch I'm applying to the trunk.  The patch for 3.2.1 will be a
> bit different.

Here's the patch for 3.2.1.  It also includes an earlier deferred patch for
PR 5607.

2002-08-22  Jason Merrill  <jason@redhat.com>

	* langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
	* langhooks.c (lhd_expr_size): Define default.
	* langhooks.h (struct lang_hooks): Add expr_size.
	* explow.c (expr_size): Call it.
	(int_expr_size): New fn.
	* expr.h: Declare it.
	* expr.c (expand_expr) [CONSTRUCTOR]: Use it to calculate how 
	much to store.
cp/
	PR c++/5607
	* search.c (check_final_overrider): No longer static.
	* class.c (update_vtable_entry_for_fn): Call it.
	* cp-tree.h: Adjust.

	* cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
	(cp_expr_size): New fn.
	* call.c (convert_arg_to_ellipsis): Promote non-POD warning to error.
	* typeck.c (build_modify_expr): Don't use save_expr on an lvalue.

*** ./gcc/cp/call.c.~1~	Thu Aug 22 16:42:23 2002
--- ./gcc/cp/call.c	Wed Aug 21 01:19:19 2002
*************** convert_arg_to_ellipsis (arg)
*** 4022,4030 ****
    
    if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
      {
!       /* Undefined behaviour [expr.call] 5.2.2/7.  */
!       warning ("cannot pass objects of non-POD type `%#T' through `...'",
! 		  TREE_TYPE (arg));
      }
  
    return arg;
--- 4022,4033 ----
    
    if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
      {
!       /* Undefined behaviour [expr.call] 5.2.2/7.  We used to just warn
! 	 here and do a bitwise copy, but now cp_expr_size will abort if we
! 	 try to do that.  */
!       error ("cannot pass objects of non-POD type `%#T' through `...'",
! 	     TREE_TYPE (arg));
!       arg = error_mark_node;
      }
  
    return arg;
*** ./gcc/cp/class.c.~1~	Thu Aug 22 16:42:24 2002
--- ./gcc/cp/class.c	Wed Aug 21 01:19:03 2002
*************** update_vtable_entry_for_fn (t, binfo, fn
*** 2454,2459 ****
--- 2454,2463 ----
    if (overrider == error_mark_node)
      return;
  
+   /* Check for unsupported covariant returns again now that we've
+      calculated the base offsets.  */
+   check_final_overrider (TREE_PURPOSE (overrider), fn);
+ 
    /* Assume that we will produce a thunk that convert all the way to
       the final overrider, and not to an intermediate virtual base.  */
    virtual_base = NULL_TREE;
*** ./gcc/cp/cp-lang.c.~1~	Thu Aug 22 16:42:24 2002
--- ./gcc/cp/cp-lang.c	Wed Aug 21 01:19:03 2002
*************** Boston, MA 02111-1307, USA.  */
*** 28,34 ****
  #include "langhooks.h"
  #include "langhooks-def.h"
  
! static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
  
  #undef LANG_HOOKS_NAME
  #define LANG_HOOKS_NAME "GNU C++"
--- 28,35 ----
  #include "langhooks.h"
  #include "langhooks-def.h"
  
! static HOST_WIDE_INT cxx_get_alias_set		PARAMS ((tree));
! static tree cp_expr_size			PARAMS ((tree));
  
  #undef LANG_HOOKS_NAME
  #define LANG_HOOKS_NAME "GNU C++"
*************** static HOST_WIDE_INT cxx_get_alias_set P
*** 91,96 ****
--- 92,99 ----
  #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
  #undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
  #define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
+ #undef LANG_HOOKS_EXPR_SIZE
+ #define LANG_HOOKS_EXPR_SIZE cp_expr_size
  
  /* Each front end provides its own hooks, for toplev.c.  */
  const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
*************** cxx_get_alias_set (t)
*** 108,110 ****
--- 111,138 ----
  
    return c_common_get_alias_set (t);
  }
+ 
+ /* Langhook for expr_size: Tell the backend that the value of an expression
+    of non-POD class type does not include any tail padding; a derived class
+    might have allocated something there.  */
+ 
+ static tree
+ cp_expr_size (exp)
+      tree exp;
+ {
+   if (CLASS_TYPE_P (TREE_TYPE (exp)))
+     {
+       /* The backend should not be interested in the size of an expression
+ 	 of a type with both of these set; all copies of such types must go
+ 	 through a constructor or assignment op.  */
+       if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp))
+ 	  && TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)))
+ 	abort ();
+       /* This would be wrong for a type with virtual bases, but they are
+ 	 caught by the abort above.  */
+       return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp));
+     }
+   else
+     /* Use the default code.  */
+     return lhd_expr_size (exp);
+ }
*** ./gcc/cp/cp-tree.h.~1~	Thu Aug 22 16:42:24 2002
--- ./gcc/cp/cp-tree.h	Wed Aug 21 01:19:03 2002
*************** extern tree lookup_conversions			PARAMS 
*** 4084,4089 ****
--- 4084,4090 ----
  extern tree binfo_for_vtable			PARAMS ((tree));
  extern tree binfo_from_vbase			PARAMS ((tree));
  extern tree look_for_overrides_here		PARAMS ((tree, tree));
+ extern int check_final_overrider		PARAMS ((tree, tree));
  extern tree dfs_walk                            PARAMS ((tree,
  						       tree (*) (tree, void *),
  						       tree (*) (tree, void *),
*** ./gcc/cp/search.c.~1~	Thu Aug 22 16:42:24 2002
--- ./gcc/cp/search.c	Wed Aug 21 01:19:03 2002
*************** static tree dfs_push_decls PARAMS ((tree
*** 100,106 ****
  static tree dfs_unuse_fields PARAMS ((tree, void *));
  static tree add_conversions PARAMS ((tree, void *));
  static int covariant_return_p PARAMS ((tree, tree));
- static int check_final_overrider PARAMS ((tree, tree));
  static int look_for_overrides_r PARAMS ((tree, tree));
  static struct search_level *push_search_level
  	PARAMS ((struct stack_level *, struct obstack *));
--- 100,105 ----
*************** covariant_return_p (brettype, drettype)
*** 1800,1806 ****
  /* Check that virtual overrider OVERRIDER is acceptable for base function
     BASEFN. Issue diagnostic, and return zero, if unacceptable.  */
  
! static int
  check_final_overrider (overrider, basefn)
       tree overrider, basefn;
  {
--- 1799,1805 ----
  /* Check that virtual overrider OVERRIDER is acceptable for base function
     BASEFN. Issue diagnostic, and return zero, if unacceptable.  */
  
! int
  check_final_overrider (overrider, basefn)
       tree overrider, basefn;
  {
*** ./gcc/cp/typeck.c.~1~	Thu Aug 22 16:42:24 2002
--- ./gcc/cp/typeck.c	Wed Aug 21 01:19:03 2002
*************** build_modify_expr (lhs, modifycode, rhs)
*** 5450,5456 ****
  	   so the code to compute it is only emitted once.  */
  	tree cond;
  
! 	rhs = save_expr (rhs);
  	
  	/* Check this here to avoid odd errors when trying to convert
  	   a throw to the type of the COND_EXPR.  */
--- 5450,5459 ----
  	   so the code to compute it is only emitted once.  */
  	tree cond;
  
! 	if (lvalue_p (rhs))
! 	  rhs = stabilize_reference (rhs);
! 	else
! 	  rhs = save_expr (rhs);
  	
  	/* Check this here to avoid odd errors when trying to convert
  	   a throw to the type of the COND_EXPR.  */
*** ./gcc/explow.c.~1~	Thu Aug 22 16:42:22 2002
--- ./gcc/explow.c	Thu Aug 22 16:29:55 2002
*************** Software Foundation, 59 Temple Place - S
*** 34,39 ****
--- 34,40 ----
  #include "insn-config.h"
  #include "ggc.h"
  #include "recog.h"
+ #include "langhooks.h"
  
  static rtx break_out_memory_refs	PARAMS ((rtx));
  static void emit_stack_probe		PARAMS ((rtx));
*************** rtx
*** 285,304 ****
  expr_size (exp)
       tree exp;
  {
!   tree size;
! 
!   if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
!       && DECL_SIZE_UNIT (exp) != 0)
!     size = DECL_SIZE_UNIT (exp);
!   else
!     size = size_in_bytes (TREE_TYPE (exp));
  
    if (TREE_CODE (size) != INTEGER_CST
        && contains_placeholder_p (size))
      size = build (WITH_RECORD_EXPR, sizetype, size, exp);
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
  
  }
  
  /* Return a copy of X in which all memory references
--- 286,318 ----
  expr_size (exp)
       tree exp;
  {
!   tree size = (*lang_hooks.expr_size) (exp);
  
    if (TREE_CODE (size) != INTEGER_CST
        && contains_placeholder_p (size))
      size = build (WITH_RECORD_EXPR, sizetype, size, exp);
  
    return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
+ }
+ 
+ /* Return a wide integer for the size in bytes of the value of EXP, or -1
+    if the size can vary or is larger than an integer.  */
+ 
+ HOST_WIDE_INT
+ int_expr_size (exp)
+      tree exp;
+ {
+   tree t = (*lang_hooks.expr_size) (exp);
+ 
+   if (t == 0
+       || TREE_CODE (t) != INTEGER_CST
+       || TREE_OVERFLOW (t)
+       || TREE_INT_CST_HIGH (t) != 0
+       /* If the result would appear negative, it's too big to represent.  */
+       || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
+     return -1;
  
+   return TREE_INT_CST_LOW (t);
  }
  
  /* Return a copy of X in which all memory references
*** ./gcc/expr.c.~1~	Thu Aug 22 16:42:22 2002
--- ./gcc/expr.c	Thu Aug 22 16:29:56 2002
*************** expand_expr (exp, target, tmode, modifie
*** 6661,6668 ****
  						       * TYPE_QUAL_CONST))),
  			     0, TREE_ADDRESSABLE (exp), 1);
  
! 	  store_constructor (exp, target, 0,
! 			     int_size_in_bytes (TREE_TYPE (exp)));
  	  return target;
  	}
  
--- 6661,6667 ----
  						       * TYPE_QUAL_CONST))),
  			     0, TREE_ADDRESSABLE (exp), 1);
  
! 	  store_constructor (exp, target, 0, int_expr_size (exp));
  	  return target;
  	}
  
*** ./gcc/expr.h.~1~	Thu Aug 22 16:42:22 2002
--- ./gcc/expr.h	Thu Aug 22 16:29:56 2002
*************** extern unsigned int case_values_threshol
*** 548,553 ****
--- 548,557 ----
  /* Return an rtx for the size in bytes of the value of an expr.  */
  extern rtx expr_size PARAMS ((tree));
  
+ /* Return a wide integer for the size in bytes of the value of EXP, or -1
+    if the size can vary or is larger than an integer.  */
+ extern HOST_WIDE_INT int_expr_size PARAMS ((tree));
+ 
  extern rtx lookup_static_chain PARAMS ((tree));
  
  /* Convert a stack slot address ADDR valid in function FNDECL
*** ./gcc/langhooks-def.h.~1~	Thu Aug 22 16:42:23 2002
--- ./gcc/langhooks-def.h	Wed Aug 21 01:19:04 2002
*************** extern int lhd_staticp PARAMS ((tree));
*** 48,53 ****
--- 48,54 ----
  extern void lhd_clear_binding_stack PARAMS ((void));
  extern void lhd_print_tree_nothing PARAMS ((FILE *, tree, int));
  extern void lhd_set_yydebug PARAMS ((int));
+ extern tree lhd_expr_size PARAMS ((tree));
  
  /* Declarations of default tree inlining hooks.  */
  tree lhd_tree_inlining_walk_subtrees		PARAMS ((tree *, int *,
*************** tree lhd_tree_inlining_convert_parm_for_
*** 85,90 ****
--- 86,92 ----
  #define LANG_HOOKS_PRINT_TYPE		lhd_print_tree_nothing
  #define LANG_HOOKS_PRINT_IDENTIFIER	lhd_print_tree_nothing
  #define LANG_HOOKS_SET_YYDEBUG		lhd_set_yydebug
+ #define LANG_HOOKS_EXPR_SIZE		lhd_expr_size
  
  /* Tree inlining hooks.  */
  #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES lhd_tree_inlining_walk_subtrees
*************** int lhd_tree_dump_type_quals			PARAMS ((
*** 156,161 ****
--- 158,164 ----
    LANG_HOOKS_PRINT_TYPE, \
    LANG_HOOKS_PRINT_IDENTIFIER, \
    LANG_HOOKS_SET_YYDEBUG, \
+   LANG_HOOKS_EXPR_SIZE, \
    LANG_HOOKS_TREE_INLINING_INITIALIZER, \
    LANG_HOOKS_TREE_DUMP_INITIALIZER \
  }
*** ./gcc/langhooks.c.~1~	Thu Aug 22 16:42:23 2002
--- ./gcc/langhooks.c	Wed Aug 21 01:19:04 2002
*************** lhd_tree_dump_type_quals (t)
*** 303,305 ****
--- 303,318 ----
    return TYPE_QUALS (t);
  }
  
+ /* lang_hooks.expr_size: Determine the size of the value of an expression T
+    in a language-specific way.  Returns a tree for the size in bytes.  */
+ 
+ tree
+ lhd_expr_size (exp)
+      tree exp;
+ {
+   if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
+       && DECL_SIZE_UNIT (exp) != 0)
+     return DECL_SIZE_UNIT (exp);
+   else
+     return size_in_bytes (TREE_TYPE (exp));
+ }
*** ./gcc/langhooks.h.~1~	Thu Aug 22 16:42:23 2002
--- ./gcc/langhooks.h	Wed Aug 21 01:19:04 2002
*************** struct lang_hooks
*** 156,161 ****
--- 156,167 ----
       warning that the front end does not use such a parser.  */
    void (*set_yydebug) PARAMS ((int));
  
+   /* Called from expr_size to calculate the size of the value of an
+      expression in a language-dependent way.  Returns a tree for the size
+      in bytes.  A frontend can call lhd_expr_size to get the default
+      semantics in cases that it doesn't want to handle specially.  */
+   tree (*expr_size) PARAMS ((tree));
+ 
    struct lang_hooks_for_tree_inlining tree_inlining;
    
    struct lang_hooks_for_tree_dump tree_dump;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]