class.c (add_implicitly_declared_members): Use classtype_has_move_assign_or_move_ctor_p.
authorNathan Sidwell <nathan@acm.org>
Wed, 19 Jul 2017 13:28:21 +0000 (13:28 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 19 Jul 2017 13:28:21 +0000 (13:28 +0000)
* 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.

From-SVN: r250344

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/method.c
gcc/cp/tree.c

index 6a87cfc..597c6b3 100644 (file)
@@ -1,5 +1,16 @@
 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.
 
index 885322c..4b9b93a 100644 (file)
@@ -150,7 +150,6 @@ static void build_base_fields (record_layout_info, splay_tree, tree *);
 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;
@@ -3385,7 +3384,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
   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]
@@ -5457,50 +5456,36 @@ type_has_virtual_destructor (tree type)
   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;
index c7bf4c7..a76906d 100644 (file)
@@ -6023,7 +6023,7 @@ extern tree default_init_uninitialized_part (tree);
 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);
index 1dfa186..3c57b41 100644 (file)
@@ -1809,7 +1809,7 @@ maybe_explain_implicit_delete (tree decl)
        }
       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 "
@@ -2371,10 +2371,10 @@ lazily_declare_fn (special_function_kind sfk, tree type)
      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)
index 64d4b28..2122450 100644 (file)
@@ -3976,7 +3976,7 @@ type_has_nontrivial_copy_init (const_tree type)
       else if (CLASSTYPE_LAZY_COPY_CTOR (t))
        {
          saw_copy = true;
-         if (classtype_has_user_move_assign_or_move_ctor_p (t))
+         if (classtype_has_move_assign_or_move_ctor_p (t, true))
            /* [class.copy]/8 If the class definition declares a move
               constructor or move assignment operator, the implicitly declared
               copy constructor is defined as deleted.... */;