Commit f7f36e3d by Jason Merrill Committed by Jason Merrill

PR c++/90171 - reorganize usual_deallocation_fn_p

When fixing 90171 it struck me as undesirable to have so many separate
functions that all needed to know about the definition of a usual
deallocation function.  So this patch condenses them into one.  I left
destroying_delete_p because it is used by other files as well.

	* call.c (struct dealloc_info): New.
	(usual_deallocation_fn_p): Take a dealloc_info*.
	(aligned_deallocation_fn_p, sized_deallocation_fn_p): Remove.
	(build_op_delete_call): Adjust.

From-SVN: r270986
parent 7f16ac89
2019-05-06 Jason Merrill <jason@redhat.com>
PR c++/90171 - reorganize usual_deallocation_fn_p
* call.c (struct dealloc_info): New.
(usual_deallocation_fn_p): Take a dealloc_info*.
(aligned_deallocation_fn_p, sized_deallocation_fn_p): Remove.
(build_op_delete_call): Adjust.
2019-05-07 Jason Merrill <jason@redhat.com> 2019-05-07 Jason Merrill <jason@redhat.com>
PR c++/86485 - -Wmaybe-unused with empty class ?: PR c++/86485 - -Wmaybe-unused with empty class ?:
......
...@@ -6348,63 +6348,22 @@ destroying_delete_p (tree t) ...@@ -6348,63 +6348,22 @@ destroying_delete_p (tree t)
return std_destroying_delete_t_p (type) ? type : NULL_TREE; return std_destroying_delete_t_p (type) ? type : NULL_TREE;
} }
/* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation struct dealloc_info
function (3.7.4.2 [basic.stc.dynamic.deallocation]) with a parameter of
std::align_val_t. */
static bool
aligned_deallocation_fn_p (tree t)
{ {
if (!aligned_new_threshold) bool sized;
return false; bool aligned;
tree destroying;
/* A template instance is never a usual deallocation function, };
regardless of its signature. */
if (TREE_CODE (t) == TEMPLATE_DECL
|| primary_template_specialization_p (t))
return false;
tree a = FUNCTION_ARG_CHAIN (t);
if (destroying_delete_p (t))
a = TREE_CHAIN (a);
if (same_type_p (TREE_VALUE (a), align_type_node)
&& TREE_CHAIN (a) == void_list_node)
return true;
if (!same_type_p (TREE_VALUE (a), size_type_node))
return false;
a = TREE_CHAIN (a);
if (a && same_type_p (TREE_VALUE (a), align_type_node)
&& TREE_CHAIN (a) == void_list_node)
return true;
return false;
}
/* Returns true if FN is a usual deallocation fn with a size_t parameter. */ /* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation
function (3.7.4.2 [basic.stc.dynamic.deallocation]). If so, and DI is
non-null, also set *DI. */
static bool static bool
sized_deallocation_fn_p (tree fn) usual_deallocation_fn_p (tree t, dealloc_info *di)
{ {
tree t = FUNCTION_ARG_CHAIN (fn); if (di) *di = dealloc_info();
if (destroying_delete_p (fn))
t = TREE_CHAIN (t);
if (!t || !same_type_p (TREE_VALUE (t), size_type_node))
return false;
t = TREE_CHAIN (t);
if (t == void_list_node)
return true;
if (aligned_new_threshold && t
&& same_type_p (TREE_VALUE (t), align_type_node)
&& TREE_CHAIN (t) == void_list_node)
return true;
return false;
}
/* Returns true iff T, an element of an OVERLOAD chain, is a usual
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */
bool
usual_deallocation_fn_p (tree t)
{
/* A template instance is never a usual deallocation function, /* A template instance is never a usual deallocation function,
regardless of its signature. */ regardless of its signature. */
if (TREE_CODE (t) == TEMPLATE_DECL if (TREE_CODE (t) == TEMPLATE_DECL
...@@ -6418,17 +6377,33 @@ usual_deallocation_fn_p (tree t) ...@@ -6418,17 +6377,33 @@ usual_deallocation_fn_p (tree t)
- optionally, a parameter of type std::align_val_t. */ - optionally, a parameter of type std::align_val_t. */
bool global = DECL_NAMESPACE_SCOPE_P (t); bool global = DECL_NAMESPACE_SCOPE_P (t);
tree chain = FUNCTION_ARG_CHAIN (t); tree chain = FUNCTION_ARG_CHAIN (t);
if (!chain) if (chain && destroying_delete_p (t))
return false; {
if (destroying_delete_p (t)) if (di) di->destroying = TREE_VALUE (chain);
chain = TREE_CHAIN (chain); chain = TREE_CHAIN (chain);
if (chain == void_list_node }
|| ((!global || flag_sized_deallocation) if (chain
&& sized_deallocation_fn_p (t))) && (!global || flag_sized_deallocation)
return true; && same_type_p (TREE_VALUE (chain), size_type_node))
if (aligned_deallocation_fn_p (t)) {
return true; if (di) di->sized = true;
return false; chain = TREE_CHAIN (chain);
}
if (chain && aligned_new_threshold
&& same_type_p (TREE_VALUE (chain), align_type_node))
{
if (di) di->aligned = true;
chain = TREE_CHAIN (chain);
}
return (chain == void_list_node);
}
/* Just return whether FN is a usual deallocation function. */
bool
usual_deallocation_fn_p (tree fn)
{
return usual_deallocation_fn_p (fn, NULL);
} }
/* Build a call to operator delete. This has to be handled very specially, /* Build a call to operator delete. This has to be handled very specially,
...@@ -6457,6 +6432,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6457,6 +6432,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
{ {
tree fn = NULL_TREE; tree fn = NULL_TREE;
tree fns, fnname, type, t; tree fns, fnname, type, t;
dealloc_info di_fn = { };
if (addr == error_mark_node) if (addr == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -6575,11 +6551,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6575,11 +6551,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter) for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter)
{ {
tree elt = *iter; tree elt = *iter;
if (usual_deallocation_fn_p (elt)) dealloc_info di_elt;
if (usual_deallocation_fn_p (elt, &di_elt))
{ {
if (!fn) if (!fn)
{ {
fn = elt; fn = elt;
di_fn = di_elt;
continue; continue;
} }
...@@ -6587,12 +6565,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6587,12 +6565,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
operator delete, all deallocation functions that are not operator delete, all deallocation functions that are not
destroying operator deletes are eliminated from further destroying operator deletes are eliminated from further
consideration. */ consideration. */
bool fn_destroying = destroying_delete_p (fn); if (di_elt.destroying != di_fn.destroying)
bool elt_destroying = destroying_delete_p (elt);
if (elt_destroying != fn_destroying)
{ {
if (elt_destroying) if (di_elt.destroying)
fn = elt; {
fn = elt;
di_fn = di_elt;
}
continue; continue;
} }
...@@ -6606,13 +6585,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6606,13 +6585,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
if (aligned_new_threshold) if (aligned_new_threshold)
{ {
bool want_align = type_has_new_extended_alignment (type); bool want_align = type_has_new_extended_alignment (type);
bool fn_align = aligned_deallocation_fn_p (fn); if (di_elt.aligned != di_fn.aligned)
bool elt_align = aligned_deallocation_fn_p (elt);
if (elt_align != fn_align)
{ {
if (want_align == elt_align) if (want_align == di_elt.aligned)
fn = elt; {
fn = elt;
di_fn = di_elt;
}
continue; continue;
} }
} }
...@@ -6639,11 +6618,12 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6639,11 +6618,12 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
/* We need a cookie to determine the array size. */ /* We need a cookie to determine the array size. */
want_size = false; want_size = false;
} }
bool fn_size = sized_deallocation_fn_p (fn); gcc_assert (di_fn.sized != di_elt.sized);
bool elt_size = sized_deallocation_fn_p (elt); if (want_size == di_elt.sized)
gcc_assert (fn_size != elt_size); {
if (want_size == elt_size) fn = elt;
fn = elt; di_fn = di_elt;
}
} }
} }
...@@ -6678,7 +6658,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6678,7 +6658,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
} }
else else
{ {
tree destroying = destroying_delete_p (fn); tree destroying = di_fn.destroying;
if (destroying) if (destroying)
{ {
/* Strip const and volatile from addr but retain the type of the /* Strip const and volatile from addr but retain the type of the
...@@ -6696,9 +6676,9 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -6696,9 +6676,9 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
args->quick_push (addr); args->quick_push (addr);
if (destroying) if (destroying)
args->quick_push (destroying); args->quick_push (destroying);
if (sized_deallocation_fn_p (fn)) if (di_fn.sized)
args->quick_push (size); args->quick_push (size);
if (aligned_deallocation_fn_p (fn)) if (di_fn.aligned)
{ {
tree al = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (type)); tree al = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (type));
args->quick_push (al); args->quick_push (al);
......
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