From 7896267da348b7e9f4e8c930f2b3fa41577ebf45 Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 2 Nov 2016 01:50:29 +0000 Subject: 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 --- gcc/cp/class.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 15 deletions(-) (limited to 'gcc/cp/class.c') 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 = ¤t_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; -- cgit v1.2.1