[gcc r16-3960] c++: -Wmismatched-new-delete, -O0, new (nothrow)

Jason Merrill jason@gcc.gnu.org
Thu Sep 18 21:45:52 GMT 2025


https://gcc.gnu.org/g:c91e508a52d4441b6c081ea50b0a08d0f4775675

commit r16-3960-gc91e508a52d4441b6c081ea50b0a08d0f4775675
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Sep 18 13:10:54 2025 +0200

    c++: -Wmismatched-new-delete, -O0, new (nothrow)
    
    With new (nothrow) we need to check whether the allocation returned null,
    and the resulting COND_EXPR was confusing -Wmismatched-new-delete-2 at -O0.
    Let's help it out by appending the address if it's the same on both arms.
    
    gcc/cp/ChangeLog:
    
            * init.cc (build_new_1): Append alloc_node to checking COND_EXPR.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/warn/Wmismatched-new-delete-2.C: Remove xfail.

Diff:
---
 gcc/cp/init.cc                                       | 5 +++++
 gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-2.C | 3 +--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index f19794caadcb..8db84eb5e38c 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -3930,6 +3930,11 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 					   complain);
 	  rval = build_conditional_expr (input_location, ifexp, rval,
 					 alloc_node, complain);
+	  /* If there's no offset between data_addr and alloc_node, append it
+	     to help -Wmismatched-new-delete at -O0.  */
+	  if (!cookie_size)
+	    rval = build2 (COMPOUND_EXPR, TREE_TYPE (alloc_node),
+			   rval, alloc_node);
 	}
 
       /* Perform the allocation before anything else, so that ALLOC_NODE
diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-2.C b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-2.C
index d0d53b38b938..0f1877ee3e53 100644
--- a/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-2.C
+++ b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-2.C
@@ -140,9 +140,8 @@ void warn_x1_array_mismatch ()
     delete p;                 // { dg-warning "'static void X1::operator delete\\(void\\*\\)' called on pointer returned from a mismatched allocation function" }
   }
   {
-    // The following requires optimization (see warn_x1_array_mismatch()).
     X1 *p = new (std::nothrow) X1[3];
-    delete p;                 // { dg-warning "'static void X1::operator delete\\(void\\*\\)' called on pointer returned from a mismatched allocation function" "pr?????" { xfail *-*-* } }
+    delete p;                 // { dg-warning "'static void X1::operator delete\\(void\\*\\)' called on pointer returned from a mismatched allocation function" }
   }
 }


More information about the Gcc-cvs mailing list