[PATCH] ld: Avoid folding new and delete pairs

Jonathan Wakely jwakely@redhat.com
Mon Jul 1 08:43:00 GMT 2024


On 29/06/24 22:42 -0700, H.J. Lu wrote:
>GCC 15 may fold new and delete pairs, like
>
>  A *bb = new A[10];
>  delete [] bb;
>  bb = new (std::nothrow) A [10];
>  delete [] bb;
>
>as shown in
>
>https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115712
>
>Avoid folding new and delete pairs by adding a function call between new
>and delete.
>
>	* testsuite/ld-elf/dl5.cc: Include "dl5.h".
>	(A): Removed.
>	Call foo between new and delete.
>	* testsuite/ld-elf/dl5.h: New file.
>	* testsuite/ld-elf/new.cc: Include "dl5.h".
>	(foo): New function.
>
>Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>---
> ld/testsuite/ld-elf/dl5.cc | 13 +++----------
> ld/testsuite/ld-elf/dl5.h  | 10 ++++++++++
> ld/testsuite/ld-elf/new.cc |  6 ++++++
> 3 files changed, 19 insertions(+), 10 deletions(-)
> create mode 100644 ld/testsuite/ld-elf/dl5.h
>
>diff --git a/ld/testsuite/ld-elf/dl5.cc b/ld/testsuite/ld-elf/dl5.cc
>index cc404553f93..77dbb62f3d5 100644
>--- a/ld/testsuite/ld-elf/dl5.cc
>+++ b/ld/testsuite/ld-elf/dl5.cc
>@@ -1,6 +1,7 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <new>
>+#include "dl5.h"
>
> int pass = 0;
>
>@@ -30,22 +31,14 @@ operator delete (void *ptr) throw ()
>     free (ptr);
> }
>
>-class A
>-{
>-public:
>-  A() {}
>-  ~A() { }
>-  int a;
>-  int b;
>-};
>-
>-
> int
> main (void)
> {
>   A *bb = new A[10];
>   delete [] bb;
>+  foo (bb);

Shouldn't this call be *before* deleting the memory? bb is an invalid
pointer value at this point, and so copying it to initialize the
parameter of foo(A*) has implementation-defined behaviour. It's fine
with GCC, but could in theory trap for some implementations.


>   bb = new (std::nothrow) A [10];
>+  foo (bb);
>   delete [] bb;
>
>   if (pass == 4)
>diff --git a/ld/testsuite/ld-elf/dl5.h b/ld/testsuite/ld-elf/dl5.h
>new file mode 100644
>index 00000000000..0d4a7c1bfa3
>--- /dev/null
>+++ b/ld/testsuite/ld-elf/dl5.h
>@@ -0,0 +1,10 @@
>+class A
>+{
>+public:
>+  A() {}
>+  ~A() { }
>+  int a;
>+  int b;
>+};
>+
>+extern void foo (A *);
>diff --git a/ld/testsuite/ld-elf/new.cc b/ld/testsuite/ld-elf/new.cc
>index 513cf2f3ad6..b038d770c6d 100644
>--- a/ld/testsuite/ld-elf/new.cc
>+++ b/ld/testsuite/ld-elf/new.cc
>@@ -1,4 +1,5 @@
> #include <new>
>+#include "dl5.h"
>
> using std::bad_alloc;
>
>@@ -45,3 +46,8 @@ operator new[] (std::size_t sz, const std::nothrow_t& nothrow) throw()
> {
>   return ::operator new(sz, nothrow);
> }
>+
>+void
>+foo (A *)
>+{
>+}
>-- 
>2.45.2
>



More information about the Binutils mailing list