From 3f5a0fdefbb4bd69547b7275da08f712b18a972e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 15 Nov 2018 13:22:15 +0000 Subject: [PATCH] [C++ DR 2336] Clean up synth walkers first 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 | 12 ++++ gcc/cp/cp-tree.h | 8 ++- gcc/cp/method.c | 141 +++++++++++++++++++---------------------------- 3 files changed, 73 insertions(+), 88 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7e6ba17669d..f8efe7de9c7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2018-11-15 Nathan Sidwell + + * 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 * parser.c (make_id_declarator): Add location_t parameter. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bfb88de9e34..dbde05fb809 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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], diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 2de2d105224..ebf14c52e09 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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 *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); -- 2.30.2