Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [class.dtor]
Link to reflector thread (if any):
Issue description:
[class.dtor] p13 reads:
[...] and, if X is the most derived class ([class.base.init]), its destructor calls the destructors for X's virtual base classes. [...]
When the destructor is implicitly invoked, the structure of objects to be destroy are statically known, and thus it's clear whether every X is the most derived class.
However, if the destructor is explicitly invoked, there can be situations where the structure of the explicitly destroyed object is not statically known. As a result, it may be unclear to the implementation whether destructors need to or not to be called for virtual base class subobjects.
E.g. in the following example, does the explicit destructor invocation call B::~B?
struct B {
B() = default;
~B() { /* some operations */ }
};
struct DX : virtual B {};
struct DY : virtual B {};
struct DZ : DX, DY {};
template<class T>
union NoDestroy {
T val;
NoDestroy() : val() {}
NoDestroy(const NoDestroy&) = delete;
NoDestroy &operator=(const NoDestroy&) = delete;
~NoDestroy() {}
};
int main()
{
NoDestroy<DZ> d{};
static_cast<DY&>(d.val).~DY();
}
It doesn't seem intended to require the implementation to record whether such an object is a most derived object. Current implementations call destructors for virtual base class subobjects whenever the destructor of the derived class is explicitly called. However, on some implementations (GCC and Clang), such an explicit destructor call can be only valid for most derived objects (llvm/llvm-project#74282).
Suggested resolution:
Full name of submitter (unless configured in github; will be published with the issue): Jiang An
Reference (section label): [class.dtor]
Link to reflector thread (if any):
Issue description:
[class.dtor] p13 reads:
When the destructor is implicitly invoked, the structure of objects to be destroy are statically known, and thus it's clear whether every
Xis the most derived class.However, if the destructor is explicitly invoked, there can be situations where the structure of the explicitly destroyed object is not statically known. As a result, it may be unclear to the implementation whether destructors need to or not to be called for virtual base class subobjects.
E.g. in the following example, does the explicit destructor invocation call
B::~B?It doesn't seem intended to require the implementation to record whether such an object is a most derived object. Current implementations call destructors for virtual base class subobjects whenever the destructor of the derived class is explicitly called. However, on some implementations (GCC and Clang), such an explicit destructor call can be only valid for most derived objects (llvm/llvm-project#74282).
Suggested resolution: