Commit 3f5a0fde by Nathan Sidwell Committed by Nathan Sidwell

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