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

Matthew House <mattlloydhouse at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mattlloydhouse at gmail dot com

--- Comment #4 from Matthew House <mattlloydhouse at gmail dot com> ---
Both of these example programs result in undefined behavior.

The cited subclause, C++14 12.7 [class.dtor] p3, does not apply, since the call
expression neither forms a pointer to a member nor accesses the value of a
member. Instead, the relevant subclause is C++14 12.6.2 [class.base.init] p14.
The example for that subclause demonstrates that a member function inherited
from an initialized base class may not be called directly from the derived
object until all base class subobjects are initialized.

In the first program, this->Func() calls the inherited member function Func of
Derived, but the initializer for B has not completed yet, so the behavior is
undefined. The same applies to the p->Func() call in the second program. 

However, this segfault persists if this->Func() or p->Func() is replaced with
((A*)this)->Func() or ((A*)p)->Func() in either example. The conversion doesn't
result in UB, since the construction of Derived has started, and the function
call doesn't result in UB, since the A subobject is already initialized. Thus,
the behavior of GCC is still erroneous in this case.

struct A
{
  int Func () { return x++; }
  int x = 5;
};

struct B { B (int) {} };

struct Derived : virtual A, B
{
  friend int f (Derived *p) { return ((A *) p)->Func (); }
  Derived () : A (), B (f (this)) {}
};

int main()
{
  Derived d;
}

Reply via email to