From ab5826e67ec1ecf28a5f32a63f5733293de0f1ac Mon Sep 17 00:00:00 2001 From: jason Date: Fri, 20 Nov 2009 05:03:21 +0000 Subject: [PATCH] PR c++/42115 * call.c (build_op_delete_call): Don't complain about using op delete (void *, size_t) for placement delete if there's an op delete (void *). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154357 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/call.c | 12 ++++++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/init/placement5.C | 18 ++++++++++++++++-- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c25d360eaf0..042e637f8ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2009-11-19 Jason Merrill + PR c++/42115 + * call.c (build_op_delete_call): Don't complain about using + op delete (void *, size_t) for placement delete if there's an + op delete (void *). + DR 176 permissiveness * class.c (build_self_reference): Call set_underlying_type. * decl.c (check_elaborated_type_specifier): Don't complain about diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ca6bd0b7462..3b3ccb66bad 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4622,8 +4622,20 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, allocation function, the program is ill-formed." */ if (non_placement_deallocation_fn_p (fn)) { + /* But if the class has an operator delete (void *), then that is + the usual deallocation function, so we shouldn't complain + about using the operator delete (void *, size_t). */ + for (t = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns; + t; t = OVL_NEXT (t)) + { + tree elt = OVL_CURRENT (t); + if (non_placement_deallocation_fn_p (elt) + && FUNCTION_ARG_CHAIN (elt) == void_list_node) + goto ok; + } permerror (0, "non-placement deallocation function %q+D", fn); permerror (input_location, "selected for placement delete"); + ok:; } } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a56a9c5fbb..ecebcb136a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2009-11-19 Jason Merrill + PR c++/42115 + * g++.dg/init/placement5.C: Add positive test. + DR 176 permissiveness * g++.dg/ext/injected-ttp.C: New. * g++.old-deja/g++.pt/niklas01a.C: Adjust. diff --git a/gcc/testsuite/g++.dg/init/placement5.C b/gcc/testsuite/g++.dg/init/placement5.C index bb882396cf8..1d540daca43 100644 --- a/gcc/testsuite/g++.dg/init/placement5.C +++ b/gcc/testsuite/g++.dg/init/placement5.C @@ -3,16 +3,30 @@ // placement deallocation function, would have been selected as a match for // the allocation function, the program is ill-formed. +// But we should only complain about using op delete (void *, size_t) for +// placement delete if it would also be selected for normal delete, not if +// there's also an op delete (void *). + typedef __SIZE_TYPE__ size_t; struct A { A(); - static void* operator new (size_t, size_t); - static void operator delete (void *, size_t); // { dg-error "non-placement" } + void* operator new (size_t, size_t); + void operator delete (void *, size_t); // { dg-error "non-placement" } +}; + +struct B +{ + B(); + void * operator new (size_t); + void * operator new (size_t, size_t); + void operator delete (void *); + void operator delete (void *, size_t); }; int main() { A* ap = new (24) A; // { dg-error "placement delete" } + B* bp = new (24) B; } -- 2.11.0