aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-08-02 07:57:22 -0400
committerJason Merrill <jason@gcc.gnu.org>2002-08-02 07:57:22 -0400
commita77a9a18c058d41eeb634e6c6a6f56d9bae04d55 (patch)
tree72cdfa1019e7a95a9c990b7e0b9711b69f589e01 /gcc/cp
parent367aa58580632b0bef67f5bbcc41009eb8a09381 (diff)
downloadgcc-a77a9a18c058d41eeb634e6c6a6f56d9bae04d55.zip
gcc-a77a9a18c058d41eeb634e6c6a6f56d9bae04d55.tar.gz
gcc-a77a9a18c058d41eeb634e6c6a6f56d9bae04d55.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c39
-rw-r--r--gcc/cp/cp-lang.c28
-rw-r--r--gcc/cp/typeck.c8
4 files changed, 46 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f9e22ca..e4def02 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 403d8b5..9029a70 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 a44d4b6..024534e 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 def5e68..965f3f4 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: