aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-11-02 01:50:29 +0000
committerJason Merrill <jason@redhat.com>2016-11-02 01:50:29 +0000
commitf665f89d73b872b7f10c23bcc529b622b0709f00 (patch)
tree1dffc88ff5b0ae93ef01f8ea3bba2713ee747362 /gcc/tree-inline.c
parent4720521a3804af0156bb3ce89ecfb2f1e6661772 (diff)
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: https://gcc.gnu.org/svn/gcc/trunk@241765 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index de5e5757080..6899d2a8736 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1045,6 +1045,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
copy_body_data *id = (copy_body_data *) data;
tree fn = id->src_fn;
tree new_block;
+ bool copied = false;
/* Begin by recognizing trees that we'll completely rewrite for the
inlining context. Our output for these trees is completely
@@ -1241,10 +1242,40 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 0;
return NULL;
}
+ else if (TREE_CODE (*tp) == COND_EXPR)
+ {
+ tree cond = TREE_OPERAND (*tp, 0);
+ walk_tree (&cond, copy_tree_body_r, data, NULL);
+ tree folded = fold (cond);
+ if (TREE_CODE (folded) == INTEGER_CST)
+ {
+ /* Only copy the taken branch; for a C++ base constructor clone
+ inherited from a virtual base, copying the other branch leads
+ to references to parameters that were optimized away. */
+ tree branch = (integer_nonzerop (folded)
+ ? TREE_OPERAND (*tp, 1)
+ : TREE_OPERAND (*tp, 2));
+ tree type = TREE_TYPE (*tp);
+ if (VOID_TYPE_P (type)
+ || type == TREE_TYPE (branch))
+ {
+ *tp = branch;
+ return copy_tree_body_r (tp, walk_subtrees, data);
+ }
+ }
+ /* Avoid copying the condition twice. */
+ copy_tree_r (tp, walk_subtrees, NULL);
+ TREE_OPERAND (*tp, 0) = cond;
+ walk_tree (&TREE_OPERAND (*tp, 1), copy_tree_body_r, data, NULL);
+ walk_tree (&TREE_OPERAND (*tp, 2), copy_tree_body_r, data, NULL);
+ *walk_subtrees = 0;
+ copied = true;
+ }
/* Here is the "usual case". Copy this tree node, and then
tweak some special cases. */
- copy_tree_r (tp, walk_subtrees, NULL);
+ if (!copied)
+ copy_tree_r (tp, walk_subtrees, NULL);
/* If EXPR has block defined, map it to newly constructed block.
When inlining we want EXPRs without block appear in the block