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