aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-11-15 13:22:15 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-11-15 13:22:15 +0000
commit3f5a0fdefbb4bd69547b7275da08f712b18a972e (patch)
tree1d908115a1451ca2b4c7fedf642f79dfcfc55297
parente99d38d0e1193a931741341af75a8c86ef654306 (diff)
downloadgcc-3f5a0fdefbb4bd69547b7275da08f712b18a972e.zip
gcc-3f5a0fdefbb4bd69547b7275da08f712b18a972e.tar.gz
gcc-3f5a0fdefbb4bd69547b7275da08f712b18a972e.tar.bz2
[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
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/method.c141
3 files changed, 73 insertions, 88 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7e6ba17..f8efe7d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bfb88de..dbde05f 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 2de2d10..ebf14c5 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<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);