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

            Bug ID: 95321
           Summary: Run-time crash on valid destructor code
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fxcoudert at gcc dot gnu.org
  Target Milestone: ---

// Run-time crash with g++ >= 9 and -Ox, x > 1
// Works perfectly with g++ <= 8.3
class IDestroyable
{
protected:
    virtual void  Destroy() = 0;

public:
    void operator delete (void * ptr)
    {
        if (ptr != nullptr) static_cast<IDestroyable *>(ptr)->Destroy();
    }
};

class IToto
{
public:
    virtual void  Toto() = 0;
};

class ITotoDestroyable : public IToto, public IDestroyable
{
public:
    void operator delete (void * ptr)
    {
        if (ptr != nullptr) delete static_cast<IDestroyable
*>(static_cast<ITotoDestroyable *>(ptr));
    }
};

template <typename INTERFACE>
class DestroyableBase : public INTERFACE
{
protected:
    virtual void  Destroy()
    {
        ::delete this;
    }

public:
    virtual ~DestroyableBase()
    {
    }

    void operator delete (void * ptr)
    {
        ::operator delete (ptr);
    }
};

#include <iostream>

class TotoDestroyable : public DestroyableBase<ITotoDestroyable>
{
public:
    ~TotoDestroyable()
    {
        std::cout << "OK Destroyed !\n";
    }

    void  Toto()
    {
        std::cout << "Toto !\n";
    }
};

int main()
{
    ITotoDestroyable * foo = new TotoDestroyable();
    // Uncomment to workaround the crash
    // foo->Toto();
    delete foo;
}



Segfaults at runtime when compiled with G++ >= 9 and -O1 or higher.

Process 52619 launched: '/tmp/a.out' (x86_64)
Process 52619 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=1, address=0x0)
    frame #0: 0x0000000100000d44 a.out`main [inlined] IDestroyable::operator
delete(ptr=0x0000000100604858) at a.cpp:11:70
   8    public:
   9        void operator delete (void * ptr)
   10       {
-> 11           if (ptr != nullptr) static_cast<IDestroyable
*>(ptr)->Destroy();
   12       }
   13   };
   14

Reply via email to