langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.

* 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.
        * expr.c (store_expr): Don't copy an expression of size zero.
        (expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
        to store.
        * Makefile.in (builtins.o): Depend on langhooks.h.

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

From-SVN: r55983
This commit is contained in:
Jason Merrill 2002-08-02 07:57:22 -04:00 committed by Jason Merrill
parent 367aa58580
commit a77a9a18c0
11 changed files with 86 additions and 46 deletions

View file

@ -1,3 +1,14 @@
2002-08-02 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.
* expr.c (store_expr): Don't copy an expression of size zero.
(expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
to store.
* Makefile.in (builtins.o): Depend on langhooks.h.
2002-08-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in (ra-debug.o): Depend on $(TM_P_H).

View file

@ -1427,7 +1427,7 @@ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
$(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
$(EXPR_H) langhooks.h \
libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H)

View file

@ -1,5 +1,11 @@
2002-08-02 Jason Merrill <jason@redhat.com>
* cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
(cp_expr_size): New fn.
* call.c (build_over_call): Lose empty class hackery.
(convert_arg_to_ellipsis): Promote non-POD warning to error.
* typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
* semantics.c (expand_body): Do tree optimization in the function
context, too.

View file

@ -4111,9 +4111,12 @@ convert_arg_to_ellipsis (arg)
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));
/* 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;
@ -4436,15 +4439,8 @@ build_over_call (cand, args, flags)
else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
}
else if ((!real_lvalue_p (arg)
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
/* Empty classes have padding which can be hidden
inside an (empty) base of the class. This must not
be touched as it might overlay things. When the
gcc core learns about empty classes, we can treat it
like other classes. */
&& !(is_empty_class (DECL_CONTEXT (fn))
&& TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))))
else if (!real_lvalue_p (arg)
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
tree address;
tree to = stabilize_reference
@ -4466,24 +4462,7 @@ build_over_call (cand, args, flags)
(build_indirect_ref (TREE_VALUE (converted_args), 0));
arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
if (is_empty_class (TREE_TYPE (to)))
{
TREE_USED (arg) = 1;
val = build (COMPOUND_EXPR, DECL_CONTEXT (fn), arg, to);
/* Even though the assignment may not actually result in any
code being generated, we do not want to warn about the
assignment having no effect. That would be confusing to
users who may be performing the assignment as part of a
generic algorithm, for example.
Ideally, the notions of having side-effects and of being
useless would be orthogonal. */
TREE_SIDE_EFFECTS (val) = 1;
TREE_NO_UNUSED_WARNING (val) = 1;
}
else
val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
return val;
}

View file

@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
static bool cxx_warn_unused_global_decl PARAMS ((tree));
static tree cp_expr_size PARAMS ((tree));
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++"
@ -133,6 +134,8 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree));
#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
#undef LANG_HOOKS_MAKE_TYPE
#define LANG_HOOKS_MAKE_TYPE cxx_make_type
@ -280,3 +283,28 @@ cxx_warn_unused_global_decl (decl)
return true;
}
/* 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);
}

View file

@ -5077,8 +5077,9 @@ build_modify_expr (lhs, modifycode, rhs)
except that the RHS goes through a save-expr
so the code to compute it is only emitted once. */
tree cond;
tree preeval = NULL_TREE;
rhs = save_expr (rhs);
rhs = stabilize_expr (rhs, &preeval);
/* Check this here to avoid odd errors when trying to convert
a throw to the type of the COND_EXPR. */
@ -5098,10 +5099,7 @@ build_modify_expr (lhs, modifycode, rhs)
return cond;
/* Make sure the code to compute the rhs comes out
before the split. */
return build (COMPOUND_EXPR, TREE_TYPE (lhs),
/* Cast to void to suppress warning
from warn_if_unused_value. */
cp_convert (void_type_node, rhs), cond);
return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
}
case OFFSET_REF:

View file

@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#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));
@ -285,20 +286,13 @@ rtx
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));
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 copy of X in which all memory references

View file

@ -4241,6 +4241,8 @@ store_expr (exp, target, want_value)
|| (temp != target && (side_effects_p (temp)
|| side_effects_p (target))))
&& TREE_CODE (exp) != ERROR_MARK
/* If there's nothing to copy, don't bother. */
&& expr_size (exp) != const0_rtx
&& ! dont_store_target
/* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
but TARGET is not valid memory reference, TEMP will differ
@ -6810,8 +6812,7 @@ expand_expr (exp, target, tmode, modifier)
* TYPE_QUAL_CONST))),
0, TREE_ADDRESSABLE (exp), 1);
store_constructor (exp, target, 0,
int_size_in_bytes (TREE_TYPE (exp)));
store_constructor (exp, target, 0, INTVAL (expr_size (exp)));
return target;
}

View file

@ -62,6 +62,7 @@ extern void lhd_set_decl_assembler_name PARAMS ((tree));
extern bool lhd_warn_unused_global_decl PARAMS ((tree));
extern void lhd_incomplete_type_error PARAMS ((tree, tree));
extern tree lhd_type_promotes_to PARAMS ((tree));
extern tree lhd_expr_size PARAMS ((tree));
/* Declarations of default tree inlining hooks. */
tree lhd_tree_inlining_walk_subtrees PARAMS ((tree *, int *,
@ -109,6 +110,7 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
#define LANG_HOOKS_PRINT_IDENTIFIER lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_ERROR_FUNCTION lhd_print_error_function
#define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
#define LANG_HOOKS_EXPR_SIZE lhd_expr_size
#define LANG_HOOKS_FUNCTION_INIT lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_FINAL lhd_do_nothing_f
@ -247,6 +249,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_PRINT_IDENTIFIER, \
LANG_HOOKS_DECL_PRINTABLE_NAME, \
LANG_HOOKS_PRINT_ERROR_FUNCTION, \
LANG_HOOKS_EXPR_SIZE, \
LANG_HOOKS_ATTRIBUTE_TABLE, \
LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, \
LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, \

View file

@ -421,3 +421,17 @@ lhd_tree_dump_type_quals (t)
{
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));
}

View file

@ -328,6 +328,12 @@ struct lang_hooks
void (*print_error_function) PARAMS ((struct diagnostic_context *,
const char *));
/* 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));
/* Pointers to machine-independent attribute tables, for front ends
using attribs.c. If one is NULL, it is ignored. Respectively, a
table of attributes specific to the language, a table of