Commit eb0dbdc7 by Jason Merrill Committed by Jason Merrill

class.c (build_if_in_charge): Split out from build_base_path.

	* class.c (build_if_in_charge): Split out from build_base_path.

	* init.c (expand_virtual_init, expand_default_init): Use it.
	* call.c (build_special_member_call): Use it.

From-SVN: r234333
parent 07c10d8f
2016-03-18 Jason Merrill <jason@redhat.com>
* class.c (build_if_in_charge): Split out from build_base_path.
* init.c (expand_virtual_init, expand_default_init): Use it.
* call.c (build_special_member_call): Use it.
2016-03-18 Jakub Jelinek <jakub@redhat.com>
PR c++/70267
......
......@@ -8004,11 +8004,7 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
vtt = decay_conversion (vtt, complain);
if (vtt == error_mark_node)
return error_mark_node;
vtt = build3 (COND_EXPR, TREE_TYPE (vtt),
build2 (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
current_vtt_parm,
vtt);
vtt = build_if_in_charge (vtt, current_vtt_parm);
if (BINFO_SUBVTT_INDEX (binfo))
sub_vtt = fold_build_pointer_plus (vtt, BINFO_SUBVTT_INDEX (binfo));
else
......
......@@ -225,6 +225,24 @@ int n_convert_harshness = 0;
int n_compute_conversion_costs = 0;
int n_inner_fields_searched = 0;
/* Return a COND_EXPR that executes TRUE_STMT if this execution of the
'structor is in charge of 'structing virtual bases, or FALSE_STMT
otherwise. */
tree
build_if_in_charge (tree true_stmt, tree false_stmt)
{
gcc_assert (DECL_HAS_IN_CHARGE_PARM_P (current_function_decl));
tree cmp = build2 (NE_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node);
tree type = unlowered_expr_type (true_stmt);
if (VOID_TYPE_P (type))
type = unlowered_expr_type (false_stmt);
tree cond = build3 (COND_EXPR, type,
cmp, true_stmt, false_stmt);
return cond;
}
/* Convert to or from a base subobject. EXPR is an expression of type
`A' or `A*', an expression of type `B' or `B*' is returned. To
convert A to a base B, CODE is PLUS_EXPR and BINFO is the binfo for
......@@ -470,12 +488,9 @@ build_base_path (enum tree_code code,
/* Negative fixed_type_p means this is a constructor or destructor;
virtual base layout is fixed in in-charge [cd]tors, but not in
base [cd]tors. */
offset = build3 (COND_EXPR, ptrdiff_type_node,
build2 (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
v_offset,
convert_to_integer (ptrdiff_type_node,
BINFO_OFFSET (binfo)));
offset = build_if_in_charge
(convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo)),
v_offset);
else
offset = v_offset;
}
......
......@@ -5638,6 +5638,7 @@ extern tree get_function_version_dispatcher (tree);
/* in class.c */
extern tree build_vfield_ref (tree, tree);
extern tree build_if_in_charge (tree true_stmt, tree false_stmt = void_node);
extern tree build_base_path (enum tree_code, tree,
tree, int, tsubst_flags_t);
extern tree convert_to_base (tree, tree, bool, bool,
......
......@@ -1243,12 +1243,7 @@ expand_virtual_init (tree binfo, tree decl)
/* The actual initializer is the VTT value only in the subobject
constructor. In maybe_clone_body we'll substitute NULL for
the vtt_parm in the case of the non-subobject constructor. */
vtbl = build3 (COND_EXPR,
TREE_TYPE (vtbl),
build2 (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
vtbl2,
vtbl);
vtbl = build_if_in_charge (vtbl, vtbl2);
}
/* Compute the location of the vtpr. */
......@@ -1741,11 +1736,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
&parms, binfo, flags,
complain);
base = fold_build_cleanup_point_expr (void_type_node, base);
rval = build3 (COND_EXPR, void_type_node,
build2 (EQ_EXPR, boolean_type_node,
current_in_charge_parm, integer_zero_node),
base,
complete);
rval = build_if_in_charge (complete, base);
}
else
{
......
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