This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH to avoid copying tail padding (was: GCC 3.2)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 23 Aug 2002 12:42:48 +0100
- Subject: Re: PATCH to avoid copying tail padding (was: GCC 3.2)
- References: <40360000.1027723811@gandalf.codesourcery.com><200207271635.12319@enzo.bigblue.local><wvlptx6m7pd.fsf@prospero.cambridge.redhat.com><wvly9bsk9gg.fsf@prospero.cambridge.redhat.com><3000000.1028131037@gandalf.codesourcery.com><wvl8z3qjlxc.fsf@prospero.cambridge.redhat.com><wvlfzxxiicg.fsf_-_@prospero.cambridge.redhat.com>
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;