summaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-02 01:50:29 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-02 01:50:29 +0000
commit7896267da348b7e9f4e8c930f2b3fa41577ebf45 (patch)
tree1dffc88ff5b0ae93ef01f8ea3bba2713ee747362 /gcc/cp/class.c
parent36f431a6ed5f28b30834942c25cf875bccc88276 (diff)
downloadgcc-7896267da348b7e9f4e8c930f2b3fa41577ebf45.tar.gz
Implement P0136R1, Rewording inheriting constructors.
gcc/c-family/ * c.opt (-fnew-inheriting-ctors): New. * c-opts.c: Default to on for ABI 11+. gcc/cp/ * call.c (enum rejection_reason_code): Add rr_inherited_ctor. (inherited_ctor_rejection): New. (add_function_candidate): Reject inherited ctors for copying. (enforce_access): Use strip_inheriting_ctors. (print_z_candidate): Likewise. Handle rr_inherited_ctor. (convert_like_real): Avoid copying inheriting ctor parameters. (build_over_call): Likewise. A base ctor inheriting from vbase has no parms. Sorry about varargs. (joust): A local constructor beats inherited with the same convs. * class.c (add_method): Handle hiding inheriting ctors. (one_inherited_ctor): Handle new semantics. (add_implicitly_declared_members): Pass using_decl down. (build_clone): A base ctor inheriting from vbase has no parms. * cp-tree.h (DECL_INHERITED_CTOR): Store this instead of the base. (SET_DECL_INHERITED_CTOR): Likewise. (DECL_INHERITED_CTOR_BASE): Adjust. * constexpr.c: Adjust. * error.c (dump_function_decl): Decorate inheriting ctors. * init.c (emit_mem_initializers): Suppress access control in inheriting ctor. * mangle.c (write_special_name_constructor): Handle new inheriting ctor mangling. * method.c (strip_inheriting_ctors, inherited_ctor_binfo) (ctor_omit_inherited_parms, binfo_inherited_from): New. (synthesized_method_walk): Use binfo_inherited_from. Suppress access control in inheriting ctor. (deduce_inheriting_ctor): Deleted if ambiguous ctor inheritance. (maybe_explain_implicit_delete): Explain ambigous ctor inheritance. (add_one_base_init, do_build_copy_constructor): Adjust. (locate_fn_flags, explain_implicit_non_constexpr): Adjust. (implicitly_declare_fn): Adjust. (get_inherited_ctor): Remove. * name-lookup.c (do_class_using_decl): Check for indirect ctor inheritance. * optimize.c (cdtor_comdat_group): Adjust for new mangling. (maybe_clone_body): Handle omitted parms in base clone. (maybe_thunk_body): Don't thunk if base clone omits parms. * pt.c (tsubst_decl): Adjust. (instantiate_template_1): Suppress access control in inheriting ctor. (fn_type_unification): Do deduction with inherited ctor. * tree.c (special_function_p): Adjust. gcc/ * tree-inline.c (copy_tree_body_r): Only copy the taken branch of a COND_EXPR with constant condition. libiberty/ * cp-demangle.c (d_ctor_dtor_name): Handle inheriting constructor. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241765 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1a379348e5f..c6b4ed6af33 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1016,7 +1016,6 @@ add_method (tree type, tree method, tree using_decl)
bool complete_p;
bool insert_p = false;
tree current_fns;
- tree fns;
if (method == error_mark_node)
return false;
@@ -1083,8 +1082,9 @@ add_method (tree type, tree method, tree using_decl)
current_fns = insert_p ? NULL_TREE : (*method_vec)[slot];
/* Check to see if we've already got this method. */
- for (fns = current_fns; fns; fns = OVL_NEXT (fns))
+ for (tree *p = &current_fns; *p; )
{
+ tree fns = *p;
tree fn = OVL_CURRENT (fns);
tree fn_type;
tree method_type;
@@ -1092,12 +1092,14 @@ add_method (tree type, tree method, tree using_decl)
tree parms2;
if (TREE_CODE (fn) != TREE_CODE (method))
- continue;
+ goto cont;
/* Two using-declarations can coexist, we'll complain about ambiguity in
overload resolution. */
- if (using_decl && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns))
- continue;
+ if (using_decl && TREE_CODE (fns) == OVERLOAD && OVL_USED (fns)
+ /* Except handle inherited constructors specially. */
+ && ! DECL_CONSTRUCTOR_P (fn))
+ goto cont;
/* [over.load] Member function declarations with the
same name and the same parameter types cannot be
@@ -1131,7 +1133,7 @@ add_method (tree type, tree method, tree using_decl)
== FUNCTION_REF_QUALIFIED (method_type))
&& (type_memfn_quals (fn_type) != type_memfn_quals (method_type)
|| type_memfn_rqual (fn_type) != type_memfn_rqual (method_type)))
- continue;
+ goto cont;
/* For templates, the return type and template parameters
must be identical. */
@@ -1140,7 +1142,7 @@ add_method (tree type, tree method, tree using_decl)
TREE_TYPE (method_type))
|| !comp_template_parms (DECL_TEMPLATE_PARMS (fn),
DECL_TEMPLATE_PARMS (method))))
- continue;
+ goto cont;
if (! DECL_STATIC_FUNCTION_P (fn))
parms1 = TREE_CHAIN (parms1);
@@ -1178,18 +1180,38 @@ add_method (tree type, tree method, tree using_decl)
mangle_decl (method);
}
cgraph_node::record_function_versions (fn, method);
- continue;
+ goto cont;
}
- if (DECL_INHERITED_CTOR_BASE (method))
+ if (DECL_INHERITED_CTOR (method))
{
- if (DECL_INHERITED_CTOR_BASE (fn))
+ if (DECL_INHERITED_CTOR (fn))
{
+ tree basem = DECL_INHERITED_CTOR_BASE (method);
+ tree basef = DECL_INHERITED_CTOR_BASE (fn);
+ if (flag_new_inheriting_ctors)
+ {
+ if (basem == basef)
+ {
+ /* Inheriting the same constructor along different
+ paths, combine them. */
+ SET_DECL_INHERITED_CTOR
+ (fn, ovl_cons (DECL_INHERITED_CTOR (method),
+ DECL_INHERITED_CTOR (fn)));
+ /* Adjust deletedness and such. */
+ deduce_inheriting_ctor (fn);
+ /* And discard the new one. */
+ return false;
+ }
+ else
+ /* Inherited ctors can coexist until overload
+ resolution. */
+ goto cont;
+ }
error_at (DECL_SOURCE_LOCATION (method),
- "%q#D inherited from %qT", method,
- DECL_INHERITED_CTOR_BASE (method));
+ "%q#D", method);
error_at (DECL_SOURCE_LOCATION (fn),
"conflicts with version inherited from %qT",
- DECL_INHERITED_CTOR_BASE (fn));
+ basef);
}
/* Otherwise defer to the other function. */
return false;
@@ -1200,6 +1222,13 @@ add_method (tree type, tree method, tree using_decl)
/* Defer to the local function. */
return false;
}
+ else if (flag_new_inheriting_ctors
+ && DECL_INHERITED_CTOR (fn))
+ {
+ /* Hide the inherited constructor. */
+ *p = OVL_NEXT (fns);
+ continue;
+ }
else
{
error ("%q+#D cannot be overloaded", method);
@@ -1212,6 +1241,12 @@ add_method (tree type, tree method, tree using_decl)
will crash while processing the definitions. */
return false;
}
+
+ cont:
+ if (TREE_CODE (fns) == OVERLOAD)
+ p = &OVL_CHAIN (fns);
+ else
+ break;
}
/* A class should never have more than one destructor. */
@@ -3308,10 +3343,19 @@ one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
constructor CTOR. */
static void
-one_inherited_ctor (tree ctor, tree t)
+one_inherited_ctor (tree ctor, tree t, tree using_decl)
{
tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);
+ if (flag_new_inheriting_ctors)
+ {
+ ctor = implicitly_declare_fn (sfk_inheriting_constructor,
+ t, /*const*/false, ctor, parms);
+ add_method (t, ctor, using_decl);
+ TYPE_HAS_USER_CONSTRUCTOR (t) = true;
+ return;
+ }
+
tree *new_parms = XALLOCAVEC (tree, list_length (parms));
int i = 0;
for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
@@ -3412,7 +3456,7 @@ add_implicitly_declared_members (tree t, tree* access_decls,
input_location = DECL_SOURCE_LOCATION (using_decl);
if (ctor_list)
for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
- one_inherited_ctor (OVL_CURRENT (ctor_list), t);
+ one_inherited_ctor (OVL_CURRENT (ctor_list), t, using_decl);
*access_decls = TREE_CHAIN (*access_decls);
input_location = loc;
}
@@ -4772,6 +4816,11 @@ build_clone (tree fn, tree name)
}
}
+ /* A base constructor inheriting from a virtual base doesn't get the
+ arguments. */
+ if (ctor_omit_inherited_parms (fn))
+ DECL_CHAIN (DECL_CHAIN (DECL_ARGUMENTS (clone))) = NULL_TREE;
+
for (parms = DECL_ARGUMENTS (clone); parms; parms = DECL_CHAIN (parms))
{
DECL_CONTEXT (parms) = clone;