[C++ DR 2336] Clean up synth walkers first
authorNathan Sidwell <nathan@acm.org>
Thu, 15 Nov 2018 13:22:15 +0000 (13:22 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 15 Nov 2018 13:22:15 +0000 (13:22 +0000)
https://gcc.gnu.org/ml/gcc-patches/2018-11/msg01376.html
* cp-tree.h (enum special_function_kind): Reorder and comment.
* method.c (SFK_CTOR_P, SFK_DTOR_P, SFK_ASSIGN_P, SFK_COPY_P)
(SFK_MOVE_P): New predicates.
(walk_field_subobs, synthesized_method_base_walk): Drop
copy_arg_p, move_p, assign_p args.  Use new SFK predicates.  Order
parameters consistently.
(synthesized_method_walk): Drop ctor_p, copy_arg_p, move_p,
assign_p calculations.  Use new SFK predicates.  Adjust calls to
worker functions.

From-SVN: r266180

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

index 7e6ba17..f8efe7d 100644 (file)
@@ -1,3 +1,15 @@
+2018-11-15  Nathan Sidwell  <nathan@acm.org>
+
+       * cp-tree.h (enum special_function_kind): Reorder and comment.
+       * method.c (SFK_CTOR_P, SFK_DTOR_P, SFK_ASSIGN_P, SFK_COPY_P)
+       (SFK_MOVE_P): New predicates.
+       (walk_field_subobs, synthesized_method_base_walk): Drop
+       copy_arg_p, move_p, assign_p args.  Use new SFK predicates.  Order
+       parameters consistently.
+       (synthesized_method_walk): Drop ctor_p, copy_arg_p, move_p,
+       assign_p calculations.  Use new SFK predicates.  Adjust calls to
+       worker functions.
+
 2018-11-14  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * parser.c (make_id_declarator): Add location_t parameter.
index bfb88de..dbde05f 100644 (file)
@@ -5084,20 +5084,22 @@ enum special_function_kind {
   sfk_none = 0,                   /* Not a special function.  This enumeral
                              must have value zero; see
                              special_function_p.  */
+  /* The following are ordered, for use by member synthesis fns.  */
+  sfk_destructor,         /* A destructor.  */
   sfk_constructor,        /* A constructor.  */
+  sfk_inheriting_constructor, /* An inheriting constructor */
   sfk_copy_constructor,    /* A copy constructor.  */
   sfk_move_constructor,    /* A move constructor.  */
   sfk_copy_assignment,     /* A copy assignment operator.  */
   sfk_move_assignment,     /* A move assignment operator.  */
-  sfk_destructor,         /* A destructor.  */
+  /* The following are unordered.  */
   sfk_complete_destructor, /* A destructor for complete objects.  */
   sfk_base_destructor,     /* A destructor for base subobjects.  */
   sfk_deleting_destructor, /* A destructor for complete objects that
                              deletes the object after it has been
                              destroyed.  */
   sfk_conversion,         /* A conversion operator.  */
-  sfk_deduction_guide,    /* A class template deduction guide.  */
-  sfk_inheriting_constructor /* An inheriting constructor */
+  sfk_deduction_guide     /* A class template deduction guide.  */
 };
 
 /* The various kinds of linkage.  From [basic.link],
index 2de2d10..ebf14c5 100644 (file)
@@ -1283,15 +1283,26 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
     }
 }
 
+/* Categorize various special_function_kinds.  */
+#define SFK_CTOR_P(sfk) \
+  ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
+#define SFK_DTOR_P(sfk) \
+  ((sfk) == sfk_destructor)
+#define SFK_ASSIGN_P(sfk) \
+  ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
+#define SFK_COPY_P(sfk) \
+  ((sfk) == sfk_copy_constructor || (sfk) == sfk_copy_assignment)
+#define SFK_MOVE_P(sfk) \
+  ((sfk) == sfk_move_constructor || (sfk) == sfk_move_assignment)
+
 /* Subroutine of synthesized_method_walk to allow recursion into anonymous
    aggregates.  If DTOR_FROM_CTOR is true, we're walking subobject destructors
    called from a synthesized constructor, in which case we don't consider
    the triviality of the subobject destructor.  */
 
 static void
-walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
-                  int quals, bool copy_arg_p, bool move_p,
-                  bool assign_p, tree *spec_p, bool *trivial_p,
+walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
+                  int quals, tree *spec_p, bool *trivial_p,
                   bool *deleted_p, bool *constexpr_p,
                   bool diag, int flags, tsubst_flags_t complain,
                   bool dtor_from_ctor)
@@ -1315,7 +1326,7 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
        break;
 
       mem_type = strip_array_types (TREE_TYPE (field));
-      if (assign_p)
+      if (SFK_ASSIGN_P (sfk))
        {
          bool bad = true;
          if (CP_TYPE_CONST_P (mem_type) && !CLASS_TYPE_P (mem_type))
@@ -1419,19 +1430,18 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
 
       if (ANON_AGGR_TYPE_P (mem_type))
        {
-         walk_field_subobs (TYPE_FIELDS (mem_type), fnname, sfk, quals,
-                            copy_arg_p, move_p, assign_p, spec_p, trivial_p,
-                            deleted_p, constexpr_p,
+         walk_field_subobs (TYPE_FIELDS (mem_type), sfk, fnname, quals,
+                            spec_p, trivial_p, deleted_p, constexpr_p,
                             diag, flags, complain, dtor_from_ctor);
          continue;
        }
 
-      if (copy_arg_p)
+      if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
        {
          int mem_quals = cp_type_quals (mem_type) | quals;
          if (DECL_MUTABLE_P (field))
            mem_quals &= ~TYPE_QUAL_CONST;
-         argtype = build_stub_type (mem_type, mem_quals, move_p);
+         argtype = build_stub_type (mem_type, mem_quals, SFK_MOVE_P (sfk));
        }
       else
        argtype = NULL_TREE;
@@ -1449,11 +1459,10 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
    synthesized_method_walk, or its local vars.  */
 
 static tree
-synthesized_method_base_walk (tree binfo, tree base_binfo, 
-                             int quals, bool copy_arg_p,
-                             bool move_p, bool ctor_p,
+synthesized_method_base_walk (tree binfo, tree base_binfo,
+                             special_function_kind sfk, tree fnname, int quals,
                              tree *inheriting_ctor, tree inherited_parms,
-                             tree fnname, int flags, bool diag,
+                             int flags, bool diag,
                              tree *spec_p, bool *trivial_p,
                              bool *deleted_p, bool *constexpr_p)
 {
@@ -1461,8 +1470,8 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
   tree argtype = NULL_TREE;
   deferring_kind defer = dk_no_deferred;
 
-  if (copy_arg_p)
-    argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p);
+  if (SFK_COPY_P (sfk) || SFK_MOVE_P (sfk))
+    argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, SFK_MOVE_P (sfk));
   else if (inheriting_ctor
           && (inherited_binfo
               = binfo_inherited_from (binfo, base_binfo, *inheriting_ctor)))
@@ -1495,7 +1504,7 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
 
   process_subob_fn (rval, spec_p, trivial_p, deleted_p,
                    constexpr_p, diag, BINFO_TYPE (base_binfo));
-  if (ctor_p &&
+  if (SFK_CTOR_P (sfk) &&
       (!BINFO_VIRTUAL_P (base_binfo)
        || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))))
     {
@@ -1529,9 +1538,13 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
                         bool *constexpr_p, bool diag,
                         tree *inheriting_ctor, tree inherited_parms)
 {
-  tree binfo, base_binfo, fnname;
+  tree binfo, base_binfo;
   int i;
 
+  /* SFK must be exactly one category.  */
+  gcc_checking_assert (SFK_DTOR_P(sfk) + SFK_CTOR_P(sfk)
+                      + SFK_ASSIGN_P(sfk) == 1);
+
   if (spec_p)
     *spec_p = (cxx_dialect >= cxx11 ? noexcept_true_spec : empty_except_spec);
 
@@ -1556,35 +1569,20 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
       *deleted_p = false;
     }
 
-  bool ctor_p = false;
-  bool assign_p = false;
   bool check_vdtor = false;
-  switch (sfk)
-    {
-    case sfk_move_assignment:
-    case sfk_copy_assignment:
-      assign_p = true;
-      fnname = assign_op_identifier;
-      break;
+  tree fnname;
 
-    case sfk_destructor:
+if (SFK_DTOR_P (sfk))
+    {
       check_vdtor = true;
       /* The synthesized method will call base dtors, but check complete
         here to avoid having to deal with VTT.  */
       fnname = complete_dtor_identifier;
-      break;
-
-    case sfk_constructor:
-    case sfk_move_constructor:
-    case sfk_copy_constructor:
-    case sfk_inheriting_constructor:
-      ctor_p = true;
-      fnname = complete_ctor_identifier;
-      break;
-
-    default:
-      gcc_unreachable ();
     }
+  else if (SFK_ASSIGN_P (sfk))
+    fnname = assign_op_identifier;
+  else
+    fnname = complete_ctor_identifier;
 
   gcc_assert ((sfk == sfk_inheriting_constructor)
              == (inheriting_ctor && *inheriting_ctor != NULL_TREE));
@@ -1601,29 +1599,8 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
        thereof), the assignment operator selected to copy/move that
        member is a constexpr function.  */
   if (constexpr_p)
-    *constexpr_p = ctor_p || (assign_p && cxx_dialect >= cxx14);
-
-  bool move_p = false;
-  bool copy_arg_p = false;
-  switch (sfk)
-    {
-    case sfk_constructor:
-    case sfk_destructor:
-    case sfk_inheriting_constructor:
-      break;
-
-    case sfk_move_constructor:
-    case sfk_move_assignment:
-      move_p = true;
-      /* FALLTHRU */
-    case sfk_copy_constructor:
-    case sfk_copy_assignment:
-      copy_arg_p = true;
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
+    *constexpr_p = (SFK_CTOR_P (sfk)
+                   || (SFK_ASSIGN_P (sfk) && cxx_dialect >= cxx14));
 
   bool expected_trivial = type_has_trivial_fn (ctype, sfk);
   if (trivial_p)
@@ -1640,7 +1617,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
      resolution, so a constructor can be trivial even if it would otherwise
      call a non-trivial constructor.  */
   if (expected_trivial
-      && (!copy_arg_p || cxx_dialect < cxx11))
+      && (!(SFK_COPY_P (sfk) || SFK_MOVE_P (sfk)) || cxx_dialect < cxx11))
     {
       if (constexpr_p && sfk == sfk_constructor)
        {
@@ -1675,19 +1652,17 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
   for (binfo = TYPE_BINFO (ctype), i = 0;
        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
     {
-      if (!assign_p && BINFO_VIRTUAL_P (base_binfo))
+      if (!SFK_ASSIGN_P (sfk) && BINFO_VIRTUAL_P (base_binfo))
        /* We'll handle virtual bases below.  */
        continue;
 
-      tree fn = synthesized_method_base_walk (binfo, base_binfo, quals,
-                                             copy_arg_p, move_p, ctor_p,
-                                             inheriting_ctor,
-                                             inherited_parms,
-                                             fnname, flags, diag,
-                                             spec_p, trivial_p,
+      tree fn = synthesized_method_base_walk (binfo, base_binfo,
+                                             sfk, fnname, quals,
+                                             inheriting_ctor, inherited_parms,
+                                             flags, diag, spec_p, trivial_p,
                                              deleted_p, constexpr_p);
 
-      if (diag && assign_p && move_p
+      if (diag && SFK_ASSIGN_P (sfk) && SFK_MOVE_P (sfk)
          && BINFO_VIRTUAL_P (base_binfo)
          && fn && TREE_CODE (fn) == FUNCTION_DECL
          && move_fn_p (fn) && !trivial_fn_p (fn)
@@ -1716,7 +1691,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
     }
 
   vec<tree, va_gc> *vbases = CLASSTYPE_VBASECLASSES (ctype);
-  if (assign_p)
+  if (SFK_ASSIGN_P (sfk))
     /* Already examined vbases above.  */;
   else if (vec_safe_is_empty (vbases))
     /* No virtual bases to worry about.  */;
@@ -1734,24 +1709,20 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
        *constexpr_p = false;
 
       FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
-       synthesized_method_base_walk (binfo, base_binfo, quals,
-                                     copy_arg_p, move_p, ctor_p,
+       synthesized_method_base_walk (binfo, base_binfo, sfk, fnname, quals,
                                      inheriting_ctor, inherited_parms,
-                                     fnname, flags, diag,
-                                     spec_p, trivial_p,
-                                     deleted_p, constexpr_p);
+                                     flags, diag,
+                                     spec_p, trivial_p, deleted_p, constexpr_p);
     }
 
   /* Now handle the non-static data members.  */
-  walk_field_subobs (TYPE_FIELDS (ctype), fnname, sfk, quals,
-                    copy_arg_p, move_p, assign_p, spec_p, trivial_p,
-                    deleted_p, constexpr_p,
+  walk_field_subobs (TYPE_FIELDS (ctype), sfk, fnname, quals,
+                    spec_p, trivial_p, deleted_p, constexpr_p,
                     diag, flags, complain, /*dtor_from_ctor*/false);
-  if (ctor_p)
-    walk_field_subobs (TYPE_FIELDS (ctype), complete_dtor_identifier,
-                      sfk_destructor, TYPE_UNQUALIFIED, false,
-                      false, false, NULL, NULL,
-                      deleted_p, NULL,
+  if (SFK_CTOR_P (sfk))
+    walk_field_subobs (TYPE_FIELDS (ctype), sfk_destructor,
+                      complete_dtor_identifier, TYPE_UNQUALIFIED,
+                      NULL, NULL, deleted_p, NULL,
                       false, flags, complain, /*dtor_from_ctor*/true);
 
   pop_scope (scope);