Commit d395d8e7 by Jason Merrill Committed by Jason Merrill

PR c++/90171 - ICE with destroying delete with size_t parm.

The problem here was that "second parm is size_t" is false for a destroying
sized delete.  So let's introduce sized_deallocation_fn_p when that's what
we're asking, and reserve second_parm_is_size_t for the specific case of
warning about possible confusion with placement delete.

	* call.c (sized_deallocation_fn_p): New.  Use it instead of
	second_parm_is_size_t in most cases.
	(second_parm_is_size_t): Don't check for aligned.

From-SVN: r270467
parent f9eff98e
2019-04-19 Jason Merrill <jason@redhat.com>
PR c++/90171 - ICE with destroying delete with size_t parm.
* call.c (sized_deallocation_fn_p): New. Use it instead of
second_parm_is_size_t in most cases.
(second_parm_is_size_t): Don't check for aligned.
2019-04-19 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/89900
......
......@@ -6307,10 +6307,6 @@ second_parm_is_size_t (tree fn)
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;
}
......@@ -6383,6 +6379,26 @@ aligned_deallocation_fn_p (tree t)
return false;
}
/* Returns true if FN is a usual deallocation fn with a size_t parameter. */
static bool
sized_deallocation_fn_p (tree fn)
{
tree t = FUNCTION_ARG_CHAIN (fn);
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]). */
......@@ -6395,13 +6411,11 @@ usual_deallocation_fn_p (tree t)
|| primary_template_specialization_p (t))
return false;
/* If a class T has a member deallocation function named operator delete
with exactly one parameter, then that function is a usual
(non-placement) deallocation function. If class T does not declare
such an operator delete but does declare a member deallocation
function named operator delete with exactly two parameters, the second
of which has type std::size_t (18.2), then this function is a usual
deallocation function. */
/* A usual deallocation function is a deallocation function whose parameters
after the first are
- optionally, a parameter of type std::destroying_delete_t, then
- optionally, a parameter of type std::size_t, then
- optionally, a parameter of type std::align_val_t. */
bool global = DECL_NAMESPACE_SCOPE_P (t);
tree chain = FUNCTION_ARG_CHAIN (t);
if (!chain)
......@@ -6410,7 +6424,7 @@ usual_deallocation_fn_p (tree t)
chain = TREE_CHAIN (chain);
if (chain == void_list_node
|| ((!global || flag_sized_deallocation)
&& second_parm_is_size_t (t)))
&& sized_deallocation_fn_p (t)))
return true;
if (aligned_deallocation_fn_p (t))
return true;
......@@ -6625,8 +6639,8 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
/* We need a cookie to determine the array size. */
want_size = false;
}
bool fn_size = second_parm_is_size_t (fn);
bool elt_size = second_parm_is_size_t (elt);
bool fn_size = sized_deallocation_fn_p (fn);
bool elt_size = sized_deallocation_fn_p (elt);
gcc_assert (fn_size != elt_size);
if (want_size == elt_size)
fn = elt;
......@@ -6682,7 +6696,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
args->quick_push (addr);
if (destroying)
args->quick_push (destroying);
if (second_parm_is_size_t (fn))
if (sized_deallocation_fn_p (fn))
args->quick_push (size);
if (aligned_deallocation_fn_p (fn))
{
......
// PR c++/90171
// { dg-do compile { target c++2a } }
#include <new>
struct A {
void operator delete(A*, std::destroying_delete_t, std::align_val_t);
void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t);
};
void delete_A(A *a) { delete a; }
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