On December 4, 2020 6:06:20 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> 
wrote:
>Hi!
>
>As mentioned in the PR, we shouldn't treat non-replaceable operator
>new/delete (e.g. with the placement new) as replaceable ones.
>
>There is some pending discussion that perhaps operator delete called
>from
>delete if not replaceable should return some other fnspec, but can we
>handle
>that incrementally, fix this wrong-code and then deal with a missed
>optimization?  I really don't know what exactly should be returned.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok. 

Richard. 

>2020-12-04  Jakub Jelinek  <ja...@redhat.com>
>
>       PR c++/98130
>       * gimple.c (gimple_call_fnspec): Only return ".co " for replaceable
>       operator delete or ".mC" for replaceable operator new called from
>       new/delete.
>
>       * g++.dg/opt/pr98130.C: New test.
>
>--- gcc/gimple.c.jj    2020-11-26 01:14:47.528081989 +0100
>+++ gcc/gimple.c       2020-12-04 13:31:10.885766239 +0100
>@@ -1514,11 +1514,12 @@ gimple_call_fnspec (const gcall *stmt)
>      such operator, then we can treat it as free.  */
>   if (fndecl
>       && DECL_IS_OPERATOR_DELETE_P (fndecl)
>+      && DECL_IS_REPLACEABLE_OPERATOR (fndecl)
>       && gimple_call_from_new_or_delete (stmt))
>     return ".co ";
>   /* Similarly operator new can be treated as malloc.  */
>   if (fndecl
>-      && DECL_IS_OPERATOR_NEW_P (fndecl)
>+      && DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
>       && gimple_call_from_new_or_delete (stmt))
>     return "mC";
>   return "";
>--- gcc/testsuite/g++.dg/opt/pr98130.C.jj      2020-12-04 12:30:11.510988404
>+0100
>+++ gcc/testsuite/g++.dg/opt/pr98130.C 2020-12-04 12:33:05.663028984
>+0100
>@@ -0,0 +1,25 @@
>+// PR c++/98130
>+// { dg-do run { target c++11 } }
>+// { dg-options "-O2" }
>+
>+#include <new>
>+
>+typedef int *T;
>+
>+static unsigned char storage[sizeof (T)] alignas (T);
>+static T *p = (T *) storage;
>+
>+static inline __attribute__((__always_inline__)) void
>+foo (T value)
>+{
>+  new (p) T(value);
>+}
>+
>+int
>+main ()
>+{
>+  int a;
>+  foo (&a);
>+  if (!*p)
>+    __builtin_abort ();
>+}
>
>       Jakub

Reply via email to