2017-07-17 Nathan Sidwell * class.c (type_has_user_declared_move_constructor, type_has_user_declared_move_assign): Combine into ... (classtype_has_user_move_assign_or_move_ctor_p): ... this new function. * cp-tree.h (type_has_user_declared_move_constructor, type_has_user_declared_move_assign): Combine into ... (classtype_has_user_move_assign_or_move_ctor_p): ... this. Declare. * method.c (maybe_explain_implicit_delete): Use it. (lazily_declare_fn): Use it. * tree.c (type_has_nontrivial_copy_init): Use it. Index: cp/class.c =================================================================== --- cp/class.c (revision 250272) +++ cp/class.c (working copy) @@ -5491,48 +5491,30 @@ type_has_move_assign (tree t) return false; } -/* Returns true iff class T has a move constructor that was explicitly - declared in the class body. Note that this is different from - "user-provided", which doesn't include functions that are defaulted in - the class. */ +/* Returns true iff T, a class, has a user-declared move-assignment or + move-constructor. Note that this is different from + "user-provided", which doesn't include functions that are defaulted + in the class. */ bool -type_has_user_declared_move_constructor (tree t) +classtype_has_user_move_assign_or_move_ctor_p (tree t) { - if (CLASSTYPE_LAZY_MOVE_CTOR (t)) - return false; - if (!CLASSTYPE_METHOD_VEC (t)) return false; - for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter) - { - tree fn = *iter; - if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn)) + if (!CLASSTYPE_LAZY_MOVE_CTOR (t)) + for (ovl_iterator iter (lookup_fnfields_slot_nolazy (t, ctor_identifier)); + iter; ++iter) + if (!DECL_ARTIFICIAL (*iter) && move_fn_p (*iter)) return true; - } - - return false; -} - -/* Returns true iff class T has a move assignment operator that was - explicitly declared in the class body. */ -bool -type_has_user_declared_move_assign (tree t) -{ - if (CLASSTYPE_LAZY_MOVE_ASSIGN (t)) - return false; - - for (ovl_iterator iter (lookup_fnfields_slot_nolazy - (t, cp_assignment_operator_id (NOP_EXPR))); - iter; ++iter) - { - tree fn = *iter; - if (move_fn_p (fn) && !DECL_ARTIFICIAL (fn)) + if (!CLASSTYPE_LAZY_MOVE_ASSIGN (t)) + for (ovl_iterator iter (lookup_fnfields_slot_nolazy + (t, cp_assignment_operator_id (NOP_EXPR))); + iter; ++iter) + if (!DECL_ARTIFICIAL (*iter) && move_fn_p (*iter)) return true; - } - + return false; } Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 250272) +++ cp/cp-tree.h (working copy) @@ -6025,8 +6025,7 @@ extern bool type_has_constexpr_default_c extern bool type_has_virtual_destructor (tree); extern bool type_has_move_constructor (tree); extern bool type_has_move_assign (tree); -extern bool type_has_user_declared_move_constructor (tree); -extern bool type_has_user_declared_move_assign(tree); +extern bool classtype_has_user_move_assign_or_move_ctor_p (tree); extern bool type_build_ctor_call (tree); extern bool type_build_dtor_call (tree); extern void explain_non_literal_class (tree); Index: cp/method.c =================================================================== --- cp/method.c (revision 250272) +++ cp/method.c (working copy) @@ -1808,10 +1808,8 @@ maybe_explain_implicit_delete (tree decl informed = false; } else if (DECL_ARTIFICIAL (decl) - && (sfk == sfk_copy_assignment - || sfk == sfk_copy_constructor) - && (type_has_user_declared_move_constructor (ctype) - || type_has_user_declared_move_assign (ctype))) + && (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor) + && classtype_has_user_move_assign_or_move_ctor_p (ctype)) { inform (DECL_SOURCE_LOCATION (decl), "%q#D is implicitly declared as deleted because %qT " @@ -2372,10 +2370,8 @@ lazily_declare_fn (special_function_kind /* [class.copy]/8 If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted.... */ - if ((sfk == sfk_copy_assignment - || sfk == sfk_copy_constructor) - && (type_has_user_declared_move_constructor (type) - || type_has_user_declared_move_assign (type))) + if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor) + && classtype_has_user_move_assign_or_move_ctor_p (type)) DECL_DELETED_FN (fn) = true; /* A destructor may be virtual. */ Index: cp/tree.c =================================================================== --- cp/tree.c (revision 250272) +++ cp/tree.c (working copy) @@ -3976,8 +3976,7 @@ type_has_nontrivial_copy_init (const_tre else if (CLASSTYPE_LAZY_COPY_CTOR (t)) { saw_copy = true; - if (type_has_user_declared_move_constructor (t) - || type_has_user_declared_move_assign (t)) + if (classtype_has_user_move_assign_or_move_ctor_p (t)) /* [class.copy]/8 If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted.... */;