This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/42115 (excessive placement delete errors)


It occurred to me when responding to this PR that a reasonable interpretation of the standard would be that if there is an op delete (void *), the op delete (void *, size_t) isn't a usual deallocation function, so using it for placement delete is OK.

Tested x86_64-pc-linux-gnu, applied to trunk.

commit 081898d3bd656946dc0ce3b3955e395dc02e4999
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Nov 19 22:32:34 2009 -0500

    	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 *).

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ca6bd0b..3b3ccb6 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/g++.dg/init/placement5.C b/gcc/testsuite/g++.dg/init/placement5.C
index bb88239..1d540da 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;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]