https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125848
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I came up with
--- a/gcc/cp/call.cc 2026-08-27 10:33:18.600752718 +0200
+++ b/gcc/cp/call.cc 2026-09-16 14:39:48.831074327 +0200
@@ -8127,28 +8127,71 @@ build_op_delete_call_1 (enum tree_code c
if (placement)
{
- /* "A declaration of a placement deallocation function matches the
- declaration of a placement allocation function if it has the same
- number of parameters and, after parameter transformations (8.3.5),
- all parameter types except the first are identical."
+ /* For a placement allocation function, the matching deallocation
+ function is selected as follows:
- So we build up the function type we want and ask instantiate_type
- to get it for us. */
+ - Each candidate that is a function template is replaced by the
+ function template specializations (if any) generated using template
+ argument deduction with arguments as specified below.
+ - Each candidate whose parameter-type-list is not identical to that
+ of the allocation function, ignoring their respective first
+ parameters, is removed from the set of candidates.
+ - Each candidate whose associated constraints (if any) are not
+ satisfied is removed from the set of candidates.
+ - If exactly one function remains, that function is selected.
+ - Otherwise, no deallocation function is selected. */
t = FUNCTION_ARG_CHAIN (alloc_fn);
t = tree_cons (NULL_TREE, ptr_type_node, t);
t = build_function_type (void_type_node, t);
+ fn = NULL_TREE;
+ tree *args = NULL;
+ unsigned nargs = 0;
+ for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
+ {
+ if (TREE_CODE (elt) == TEMPLATE_DECL)
+ {
+ tree targs = make_tree_vec (DECL_NTPARMS (elt));
+ if (args == NULL)
+ {
+ tree arg_types = TYPE_ARG_TYPES (t), arg;
+ unsigned ia;
+ nargs = list_length (arg_types);
+ args = XALLOCAVEC (tree, nargs);
+ for (arg = arg_types, ia = 0; arg != NULL_TREE;
+ arg = TREE_CHAIN (arg), ++ia)
+ args[ia] = TREE_VALUE (arg);
+ }
+ elt = fn_type_unification (elt, NULL_TREE, targs, args,
+ nargs, void_type_node,
+ DEDUCE_EXACT, LOOKUP_NORMAL,
+ NULL, false, false);
+ if (elt == error_mark_node)
+ /* Instantiation failed. */
+ continue;
+ }
+
+ if (!constraints_satisfied_p (elt))
+ continue;
- fn = instantiate_type (t, fns, tf_none);
- if (fn == error_mark_node)
- return NULL_TREE;
+ /* See if there's a match. */
+ tree fntype = static_fn_type (elt);
+ if (!compparms (TYPE_ARG_TYPES (t), TYPE_ARG_TYPES (fntype)))
+ continue;
- fn = MAYBE_BASELINK_FUNCTIONS (fn);
+ if (fn != NULL_TREE)
+ {
+ fn = NULL_TREE;
+ break;
+ }
+ else
+ fn = elt;
+ }
/* "If the lookup finds the two-parameter form of a usual deallocation
function (3.7.4.2) and that function, considered as a placement
deallocation function, would have been selected as a match for the
allocation function, the program is ill-formed." */
- if (second_parm_is_size_t (fn))
+ if (fn && second_parm_is_size_t (fn))
{
const char *const msg1
= G_("exception cleanup for this placement new selects "
for this. On the 3 testcases from the standard that looks right, now to add
more testsuite coverage (and actually verify the right thing at runtime rather
than just by looking at gimple dump).