public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/105327] New: Bogus use-after-free warning new in GCC 12
@ 2022-04-21  7:28 boris at kolpackov dot net
  2022-12-25  0:57 ` [Bug tree-optimization/105327] " pinskia at gcc dot gnu.org
  2022-12-25  0:58 ` pinskia at gcc dot gnu.org
  0 siblings, 2 replies; 3+ messages in thread
From: boris at kolpackov dot net @ 2022-04-21  7:28 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 105327
           Summary: Bogus use-after-free warning new in GCC 12
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: boris at kolpackov dot net
  Target Milestone: ---

The following translation unit now (since 12.0) causes a bogus (AFAICS)
use-after-free warning:

$ cat <<EOF >use-after-free.cxx
#include <memory>

template <typename T>
class pointer_traits;

template <typename T>
class pointer_traits<std::shared_ptr<T>>
{
public:
  static void*
  allocate (std::size_t n)
  {
    return operator new (n);
  }

  static void
  free (void* p)
  {
    operator delete (p);
  }
};

template <typename T, typename P>
class pointer_factory
{
public:
  static P
  create ()
  {
    void* v (pointer_traits<P>::allocate (sizeof (T)));
    mem_guard g (v);
    P p (new (v) T);
    //g.release ();
    g.p_ = 0;
    return p;
  }

private:
  struct mem_guard
  {
    mem_guard (void* p): p_ (p) {}
    ~mem_guard () {if (p_) pointer_traits<P>::free (p_);}
    void release () {p_ = 0;}
    void* p_;
  };
};

struct s {};

int main ()
{
  std::shared_ptr<s> p (pointer_factory<s, std::shared_ptr<s>>::create ());
}
EOF

$ g++ -Wall -Wextra -O3 -c -std=c++23 use-after-free.cxx
In static member function ‘static void pointer_traits<std::shared_ptr<_Tp>
>::free(void*) [with T = s]’,
    inlined from ‘pointer_factory<T, P>::mem_guard::~mem_guard() [with T = s; P
= std::shared_ptr<s>]’ at use-after-free.cxx:42:52,
    inlined from ‘static P pointer_factory<T, P>::create() [with T = s; P =
std::shared_ptr<s>]’ at use-after-free.cxx:36:3,
    inlined from ‘int main()’ at use-after-free.cxx:52:74:
use-after-free.cxx:19:21: warning: pointer may be used after ‘void operator
delete(void*, std::size_t)’ [-Wuse-after-free]
   19 |     operator delete (p);
      |     ~~~~~~~~~~~~~~~~^~~
In file included from
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/bits/shared_ptr.h:53,
                 from
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/memory:77,
                 from use-after-free.cxx:1:
In constructor ‘std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Ptr = s*;
__gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’,
    inlined from ‘std::__shared_count<_Lp>::__shared_count(_Ptr,
std::false_type) [with _Ptr = s*; __gnu_cxx::_Lock_policy _Lp =
__gnu_cxx::_S_atomic]’ at
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/bits/shared_ptr_base.h:928:22,
    inlined from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Yp*) [with _Yp =
s; <template-parameter-2-2> = void; _Tp = s; __gnu_cxx::_Lock_policy _Lp =
__gnu_cxx::_S_atomic]’ at
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/bits/shared_ptr_base.h:1469:17,
    inlined from ‘std::shared_ptr<_Tp>::shared_ptr(_Yp*) [with _Yp = s;
<template-parameter-2-2> = void; _Tp = s]’ at
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/bits/shared_ptr.h:214:46,
    inlined from ‘static P pointer_factory<T, P>::create() [with T = s; P =
std::shared_ptr<s>]’ at use-after-free.cxx:32:7,
    inlined from ‘int main()’ at use-after-free.cxx:52:74:
/home/boris/work/build2/tests/modules/gcc2/gcc-install/include/c++/12.0.1/bits/shared_ptr_base.h:921:15:
note: call to ‘void operator delete(void*, std::size_t)’ here
  921 |               delete __p;
      |               ^~~~~~~~~~

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/105327] Bogus use-after-free warning new in GCC 12
  2022-04-21  7:28 [Bug c++/105327] New: Bogus use-after-free warning new in GCC 12 boris at kolpackov dot net
@ 2022-12-25  0:57 ` pinskia at gcc dot gnu.org
  2022-12-25  0:58 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-25  0:57 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I don't think this is a bogus one.
std::shared_ptr owns the pointer once it is passed, not before.
So when you do:

    mem_guard g (v);
...
    P p (new (v) T);
...
the constructor of p might cause operator new to be called with a throw (after
already taking the ownership of the argument) and the deconstructor of P is
called and you get a delete called on the argument.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bug tree-optimization/105327] Bogus use-after-free warning new in GCC 12
  2022-04-21  7:28 [Bug c++/105327] New: Bogus use-after-free warning new in GCC 12 boris at kolpackov dot net
  2022-12-25  0:57 ` [Bug tree-optimization/105327] " pinskia at gcc dot gnu.org
@ 2022-12-25  0:58 ` pinskia at gcc dot gnu.org
  1 sibling, 0 replies; 3+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-25  0:58 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Switching around the order to do:

    g.p_ = 0;
    P p (new (v) T);

Fixes the warning and I think correctly.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-12-25  0:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-21  7:28 [Bug c++/105327] New: Bogus use-after-free warning new in GCC 12 boris at kolpackov dot net
2022-12-25  0:57 ` [Bug tree-optimization/105327] " pinskia at gcc dot gnu.org
2022-12-25  0:58 ` pinskia at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).