[Bug middle-end/103993] -Wismatched-new-delete due to difference in inlining decisions

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Jan 12 18:31:02 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103993

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |100406
                 CC|                            |msebor at gcc dot gnu.org
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=100861
            Summary|Incorrect error generated   |-Wismatched-new-delete due
                   |by mismatched-new-delete    |to difference in inlining
                   |                            |decisions
           Keywords|                            |diagnostic
          Component|c++                         |middle-end

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
The reported mismatch is between

  void operator delete [](void*)

and

  void* ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new(size_t)

i.e., the array form of the global operator delete is being called on the
result of a scalar member operator new.  The deallocation function
corresponding to a member array new is a member array delete, so the warning
isn't incorrect per se.

The warning is based on the compiler's view of the optimized code, after
inlining and other transformations.  If the program provides overloads of
operators new and delete for some type and GCC inlines a call to one but not
the other, the warning will trigger because it sees a mismatch.  To avoid this
problem either prevent the inlining of both the allocation and the deallocation
function (using attribute noinline), or force both to be inlined (by declaring
them inline and attribute always_inline).  The diff below shows the latter
solution.  It's possible for GCC do the former automatically (and it does that
for a subset of these cases) but given it's not without a performance cost it
seems preferable to leave the choice up to the programmer.  Another approach
was suggested in pr101829.  See also pr100861 for a discussions of another
similar issue.

(When reporting a problem it's helpful to explain why you think it's in GCC
rather than in the submitted test case so we don't have to guess.)

$ diff -u JSimpleProcess.C JSimpleProcess-fix.C
--- JSimpleProcess.C    2022-01-12 11:06:52.787461649 -0700
+++ JSimpleProcess-fix.C        2022-01-12 11:18:30.085356124 -0700
@@ -78365,7 +78365,8 @@
   ;
   return;
 }
-template <typename PEER_STREAM, typename SYNCH_TRAITS> void *
+template <typename PEER_STREAM, typename SYNCH_TRAITS>
+inline __attribute__ ((always_inline)) void *
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new (size_t n)
 {
   ;
@@ -78378,10 +78379,11 @@
   else
     {
       dynamic_instance->set ();
-      return ::new char[n];
+      return ::operator new (n);
     }
 }
-template <typename PEER_STREAM, typename SYNCH_TRAITS> void *
+template <typename PEER_STREAM, typename SYNCH_TRAITS>
+inline __attribute__ ((always_inline)) void *
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator new (size_t n,
                                                           const
::std::nothrow_t&) throw()
 {
@@ -78395,15 +78397,16 @@
   else
     {
       dynamic_instance->set ();
-      return ::new(::std::nothrow) char[n];
+      return ::operator new(n, ::std::nothrow);
     }
 }
-template <typename PEER_STREAM, typename SYNCH_TRAITS> void
+template <typename PEER_STREAM, typename SYNCH_TRAITS>
+inline __attribute__ ((always_inline)) void
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete (void *p,
                                          const ::std::nothrow_t&) throw()
 {
   ;
-  ::delete [] static_cast <char *> (p);
+  ::operator delete (p);
 }
 template <typename PEER_STREAM, typename SYNCH_TRAITS> void
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::destroy ()
@@ -78412,11 +78415,12 @@
   if (this->mod_ == 0 && this->dynamic_ && this->closing_ == false)
     delete this;
 }
-template <typename PEER_STREAM, typename SYNCH_TRAITS> void
+template <typename PEER_STREAM, typename SYNCH_TRAITS>
+inline __attribute__ ((always_inline)) void
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::operator delete (void *obj)
 {
   ;
-  ::delete [] static_cast <char *> (obj);
+  ::operator delete (obj);
 }
 template <typename PEER_STREAM, typename SYNCH_TRAITS>
 ACE_Svc_Handler<PEER_STREAM, SYNCH_TRAITS>::ACE_Svc_Handler
(ACE_Thread_Manager *tm,


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100406
[Bug 100406] bogus/missing -Wmismatched-new-delete


More information about the Gcc-bugs mailing list