From 024f2d8923b9622fdf5d85d474ef77e36431ab81 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 24 Jun 2015 11:40:08 -0400 Subject: [PATCH] re PR c++/66501 (Default move assignment does not move array members) PR c++/66501 * class.c (type_has_nontrivial_assignment): Remove. * cp-tree.h: Remove declaration. * init.c (vec_copy_assign_is_trivial): New. (build_vec_init): Use it. From-SVN: r224904 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/class.c | 18 ------------------ gcc/cp/cp-tree.h | 1 - gcc/cp/init.c | 14 +++++++++++++- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 197bc77736a..2fa1732f779 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2015-06-24 Jason Merrill + + PR c++/66501 + * class.c (type_has_nontrivial_assignment): Remove. + * cp-tree.h: Remove declaration. + * init.c (vec_copy_assign_is_trivial): New. + (build_vec_init): Use it. + 2015-06-24 Edward Smith-Rowland <3dw4rd@verizon.net> Implement N3928 - Extending static_assert diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 88f1022dcd3..9da532e18dd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5136,24 +5136,6 @@ type_has_non_user_provided_default_constructor (tree t) return false; } -/* Return true if TYPE has some non-trivial assignment operator. */ - -bool -type_has_nontrivial_assignment (tree type) -{ - gcc_assert (TREE_CODE (type) != ARRAY_TYPE); - if (CLASS_TYPE_P (type)) - for (tree fns - = lookup_fnfields_slot_nolazy (type, ansi_assopname (NOP_EXPR)); - fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - if (!trivial_fn_p (fn)) - return true; - } - return false; -} - /* TYPE is being used as a virtual base, and has a non-trivial move assignment. Return true if this is due to there being a user-provided move assignment in TYPE or one of its subobjects; if there isn't, then diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8eb74748fda..b53aa9028e2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5295,7 +5295,6 @@ extern tree in_class_defaulted_default_constructor (tree); extern bool user_provided_p (tree); extern bool type_has_user_provided_constructor (tree); extern bool type_has_non_user_provided_default_constructor (tree); -extern bool type_has_nontrivial_assignment (tree); extern bool vbase_has_user_provided_move_assign (tree); extern tree default_init_uninitialized_part (tree); extern bool trivial_default_constructor_is_constexpr (tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 08c6c0ee0cf..530dad484c3 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3384,6 +3384,18 @@ get_temp_regvar (tree type, tree init) return decl; } +/* Subroutine of build_vec_init. Returns true if assigning to an array of + INNER_ELT_TYPE from INIT is trivial. */ + +static bool +vec_copy_assign_is_trivial (tree inner_elt_type, tree init) +{ + tree fromtype = inner_elt_type; + if (real_lvalue_p (init)) + fromtype = cp_build_reference_type (fromtype, /*rval*/false); + return is_trivially_xible (MODIFY_EXPR, inner_elt_type, fromtype); +} + /* `build_vec_init' returns tree structure that performs initialization of a vector of aggregate types. @@ -3460,7 +3472,7 @@ build_vec_init (tree base, tree maxindex, tree init, && TREE_CODE (atype) == ARRAY_TYPE && TREE_CONSTANT (maxindex) && (from_array == 2 - ? !type_has_nontrivial_assignment (inner_elt_type) + ? vec_copy_assign_is_trivial (inner_elt_type, init) : !TYPE_NEEDS_CONSTRUCTING (type)) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something -- 2.30.2