2017-07-19 Nathan Sidwell <nathan@acm.org>
+ * class.c (add_implicitly_declared_members): Use
+ classtype_has_move_assign_or_move_ctor_p.
+ (classtype_has_move_assign_or_move_ctor,
+ classtype_has_user_move_assign_or_move_ctor_p): Merge into ...
+ (classtype_has_move_assign_or_move_ctor_p): ... this new function.
+ * cp-tree.h (classtype_has_user_move_assign_or_move_ctor_p):
+ Replace with ...
+ (classtype_has_move_assign_or_move_ctor_p): ... this.
+ * method.c (maybe_explain_implicit_delete, lazily_declare_fn): Adjust.
+ * tree.c (type_has_nontrivial_copy_init): Adjust.
+
* cp-tree.h (PACK_EXPANSION_PARAMETER_PACKS,
PACK_EXPANSION_EXTRA_ARGS): Use TYPE_{MIN,MAX}_VALUE_RAW.
static void check_methods (tree);
static void remove_zero_width_bit_fields (tree);
static bool accessible_nvdtor_p (tree);
-static bool classtype_has_move_assign_or_move_ctor (tree);
/* Used by find_flexarrays and related functions. */
struct flexmems_t;
bool move_ok = false;
if (cxx_dialect >= cxx11 && CLASSTYPE_LAZY_DESTRUCTOR (t)
&& !TYPE_HAS_COPY_CTOR (t) && !TYPE_HAS_COPY_ASSIGN (t)
- && !classtype_has_move_assign_or_move_ctor (t))
+ && !classtype_has_move_assign_or_move_ctor_p (t, false))
move_ok = true;
/* [class.ctor]
return (dtor && DECL_VIRTUAL_P (dtor));
}
-/* Returns true iff class T has move assignment or move constructor. */
+/* Returns true iff T, a class, has a move-assignment or
+ move-constructor. Does not lazily declare either.
+ If USER_P is false, any move function will do. If it is true, the
+ move function must be user-declared.
-static bool
-classtype_has_move_assign_or_move_ctor (tree t)
-{
- gcc_assert (!CLASSTYPE_LAZY_MOVE_CTOR (t)
- && !CLASSTYPE_LAZY_MOVE_ASSIGN (t));
-
- for (ovl_iterator iter (lookup_fnfields_slot_nolazy
- (t, ctor_identifier)); iter; ++iter)
- if (move_fn_p (*iter))
- return true;
-
- for (ovl_iterator iter (lookup_fnfields_slot_nolazy
- (t, cp_assignment_operator_id (NOP_EXPR)));
- iter; ++iter)
- if (move_fn_p (*iter))
- return true;
-
- return false;
-}
-
-/* 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. */
+ Note that user-declared here is different from "user-provided",
+ which doesn't include functions that are defaulted in the
+ class. */
bool
-classtype_has_user_move_assign_or_move_ctor_p (tree t)
+classtype_has_move_assign_or_move_ctor_p (tree t, bool user_p)
{
+ gcc_assert (user_p
+ || (!CLASSTYPE_LAZY_MOVE_CTOR (t)
+ && !CLASSTYPE_LAZY_MOVE_ASSIGN (t)));
+
if (!CLASSTYPE_METHOD_VEC (t))
return false;
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))
+ if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
return true;
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))
+ if ((!user_p || !DECL_ARTIFICIAL (*iter)) && move_fn_p (*iter))
return true;
return false;
extern bool trivial_default_constructor_is_constexpr (tree);
extern bool type_has_constexpr_default_constructor (tree);
extern bool type_has_virtual_destructor (tree);
-extern bool classtype_has_user_move_assign_or_move_ctor_p (tree);
+extern bool classtype_has_move_assign_or_move_ctor_p (tree, bool user_declared);
extern bool type_build_ctor_call (tree);
extern bool type_build_dtor_call (tree);
extern void explain_non_literal_class (tree);
}
else if (DECL_ARTIFICIAL (decl)
&& (sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
- && classtype_has_user_move_assign_or_move_ctor_p (ctype))
+ && classtype_has_move_assign_or_move_ctor_p (ctype, true))
{
inform (DECL_SOURCE_LOCATION (decl),
"%q#D is implicitly declared as deleted because %qT "
move assignment operator, the implicitly declared copy constructor is
defined as deleted.... */
if ((sfk == sfk_copy_assignment || sfk == sfk_copy_constructor)
- && classtype_has_user_move_assign_or_move_ctor_p (type))
+ && classtype_has_move_assign_or_move_ctor_p (type, true))
DECL_DELETED_FN (fn) = true;
- /* A destructor may be virtual. */
+ /* Destructors and assignment operators may be virtual. */
if (sfk == sfk_destructor
|| sfk == sfk_move_assignment
|| sfk == sfk_copy_assignment)