diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/call.c | 39 | ||||
-rw-r--r-- | gcc/cp/cp-lang.c | 28 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 8 | ||||
-rw-r--r-- | gcc/explow.c | 10 | ||||
-rw-r--r-- | gcc/expr.c | 5 | ||||
-rw-r--r-- | gcc/langhooks-def.h | 3 | ||||
-rw-r--r-- | gcc/langhooks.c | 14 | ||||
-rw-r--r-- | gcc/langhooks.h | 6 |
11 files changed, 86 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 579e1dfc6b8..6480ba94aef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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). diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 75ba49c251b..c27b5d8f75a 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f9e22ca2388..e4def020fb7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 403d8b53ee3..9029a7072dc 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; } diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index a44d4b6b8a1..024534e2831 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -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); +} diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index def5e687509..965f3f4399d 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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: diff --git a/gcc/explow.c b/gcc/explow.c index 3cda4104672..5bc34517e8e 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -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 diff --git a/gcc/expr.c b/gcc/expr.c index 4aa0195dfb0..dddd2687770 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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; } diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 246fea93214..d8628513559 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -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, \ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 79eb7f4c2ec..e2feb067360 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -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)); +} diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 0ec3c88c29d..7ddd32c88f7 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -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 |