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

--- Comment #14 from Bernd Edlinger <bernd.edlinger at hotmail dot de> ---
Hi Jakub,

I played a bit with your proposed patch.

consider this test case:

cat test2.cc
struct A { ~A() {} A () {} A (int x) : a (x) {} virtual void f () {} virtual
int i () { return 0; } int a; };
struct E { E () { throw "something"; } E (int x) : e (x) {} virtual void f ()
{} virtual int g () { return 0; } int e; };
struct F { F () {} F (int x) : f (x) {} virtual int h () { return 0; } int f;
};
struct B : virtual A, public E, public F { B () : E (), F () {} virtual void f
() {} int b; };
struct D { D () {} D (int x) : d (x) {} virtual void f () {} int d; };
struct C : B, virtual A { C () {} } ;

int
main ()
{
  try {
    C c;
  }
  catch(...)
  {
  }
}
g++ -fsanitize=vptr  test2.cc -fdump-tree-gimple
test2.cc:6:32: runtime error: member call on address 0x7ffdf760fea0 which does
not point to an object of type 'A'
0x7ffdf760fea0: note: object has invalid vptr
 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  c5 9e 26 d9
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr

this happens only due to the redundant initialization of vptr.A in B::B(),
it is not undefined behavior:

C::C()
{
    if (1 != 0) goto <D.2984>; else goto <D.2985>;
    <D.2984>:
    D.2986 = &this->D.2844;
    A::A (D.2986);
    goto <D.2987>;
    <D.2985>:
    <D.2987>:
    try
      {
        D.2988 = &_ZTT1C + 8;
        D.2989 = &this->D.2842;
        B::B (D.2989, D.2988);
        ...
      }
    catch
      {
        if (1 != 0) goto <D.2998>; else goto <D.2999>;
        <D.2998>:
        D.3000 = &this->D.2844;
        D.3001 = D.3000->_vptr.A;  -- B initialized vptr.A to null
        D.3002 = (long unsigned int) D.3001;
        UBSAN_VPTR (D.3000, D.3002, 18446725454765570473, &_ZTI1A, 4B);
        A::~A (D.3000);
        goto <D.3003>;
        <D.2999>:
        <D.3003>:
      }

B::B() (struct B * const this, const void * * __vtt_parm)
{
  MEM[(struct  &)this] = {CLOBBER};
  this->D.2711._vptr.E = 0B;
  D.3012 = MEM[(int (*__vtbl_ptr_type) () * *)__vtt_parm];
  D.3013 = D.3012 + 18446744073709551592;
  D.3014 = MEM[(long int *)D.3013];
  D.3015 = (sizetype) D.3014;
  D.3016 = this + D.3015;
  D.3016->_vptr.A = 0B;
  this->D.2712._vptr.F = 0B;
  {
    if (0 != 0) goto <D.3017>; else goto <D.3018>;
    <D.3017>:
    D.3019 = &this->D.2716;
    A::A (D.3019);
    goto <D.3020>;
    <D.3018>:
    <D.3020>:
    try
      {
        D.3021 = &this->D.2711;
        E::E (D.3021);  -- this throws "something"

Reply via email to