C++ runtime error invalid vptr when compiling with gcc 8.1 and gcc 8.2

262 views Asked by At

I have a strange runtime error that only happens with GCC 8.2 and GCC 8.1.

When attempting to delete a class with multiple inheritances, the compiler raises a runtime error related to a corrupted virtual pointer.

This minimal example can be found in the godbolt.

https://godbolt.org/z/GYfWYdeqW

In the code snippet, it is possible to confirm that any combination in which flags fsanitize=undefined and -fno-sanitize-recover=undefined aren't present together enables the code to run successfully.

Question

What can be done in the code to enable execution with GCC 8.1 or 8.2 while using -fsanitize=undefined and C++14?

Acceptable answers:

  • Show that it is impossible to execute the code under the conditions specified.
  • Suggest a modification that enables the code to execute.

Anexes

MINIMAL CODE:

#include <iostream>
#include <string>
#include <memory>

class Base
{
public:
    virtual ~Base() {std::cout << "Deleting Base!\n";}
};

class DerivedLeft : public virtual Base
{
public:
    virtual ~DerivedLeft() override {std::cout << "Deleting DerivedLeft!\n";}
};


class DerivedRight : public virtual Base
{
public:
    virtual ~DerivedRight() override {std::cout << "Deleting DerivedRight!\n";}
    virtual void Release() noexcept = 0;
};

class CustomDeleter final
{
public:
  void operator()(DerivedRight const* ptr) const noexcept {
    DerivedRight* const non_const_ptr{const_cast<DerivedRight*>(ptr)};
    if (non_const_ptr != nullptr) {
        std::cout << "CustomDeleter working!\n";
        non_const_ptr->Release();
    }
  }
};

class Mock : 
    public DerivedLeft, 
    public DerivedRight
{
public:
    Mock() {std::cout << "Creating Mock!\n";}
    virtual ~Mock() override {std::cout << "Deleting Mock!\n";}
    void Release() noexcept override { delete this; };

    using Uptr = std::unique_ptr<Mock, CustomDeleter>;
    static Uptr Create() { return Uptr(new Mock()); }
};

int main(int, char**)
{
    auto Mock = Mock::Create();
    std::cout << "Scope End!\n";
}

ERROR

/app/example.cpp:43:30: runtime error: member call on address 0x602000000010 which does not point to an object of type 'Base'
0x602000000010: note: object has invalid vptr
 01 00 80 55  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr

Compiler flags

-fsanitize=undefined -fno-sanitize-recover=undefined
0

There are 0 answers