Hi Janus,

> Sorry, I don't understand the last sentence. Why should it call some
> "__free..." instead of "doit"? And why is that test case even affected
> by your patch (you said it would only work with explicit DEALLOCATE,
> which does not appear in that test case)?

Yes, it is as I said... In
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43986#c4 the doit() call
produces a segfault because r26 is 0 instead of the address of
__s_bar_mod_MOD_doit. With my patched version, the doit call is in
reality a _free __free_s_bar_mod_S_bar call. To better understand I
report a little portion (only the MAIN__) of the fdump-tree-original
and the testcase execution (hoping that it will be understandable...)

MAIN__ ()
{
  struct __class_foo_mod_Foo_p a;
  struct foo b;
  static struct s_bar c = {};
  static struct a_bar d = {};

  try
    {
      c.a = 0B;
      d.a.data = 0B;
      (struct __vtype_foo_mod_Foo *) a._vptr = &__vtab_foo_mod_Foo;
      a._data = &b;
      a._vptr->doit (&a);
      if (a._vptr->getit (&a) != 1)
        {
          _gfortran_abort ();
        }
      L.1:;
      (struct __vtype_foo_mod_Foo *) a._vptr = (struct
__vtype_foo_mod_Foo *) &__vtab_s_bar_mod_S_bar;
      a._data = (struct foo *) &c;
      a._vptr->doit (&a); IT REALLY WANTS TO CALL THE DOIT FUNCTION!
      if (a._vptr->getit (&a) != 2)
        {
          _gfortran_abort ();
        }
      L.2:;
      (struct __vtype_foo_mod_Foo *) a._vptr = (struct
__vtype_foo_mod_Foo *) &__vtab_a_bar_mod_A_bar;
      a._data = (struct foo *) &d;
      a._vptr->doit (&a);
      if (a._vptr->getit (&a) != 3)
        {
          _gfortran_abort ();
        }
      L.3:;
    }
  finally
    {
      if (d.a.data != 0B)
        {
          __builtin_free ((void *) d.a.data);
        }
      d.a.data = 0B;
      if (c.a != 0B)
        {
          __builtin_free ((void *) c.a);
        }
      c.a = 0B;
    }
}

An now the testcase execution with gdb:

Breakpoint 1, MAIN__ () at dynamic_dispatch_4.f03:82
82        type(s_bar), target :: c
(gdb) next
83        type(a_bar), target :: d
(gdb)
85        a => b
(gdb)
86        call a%doit
(gdb)
87        if (a%getit () .ne. 1) call abort
(gdb)
88        a => c
(gdb) step
89        call a%doit
(gdb)
s_bar_mod::__free_s_bar_mod_S_bar (tofree=...) at dynamic_dispatch_4.f03:43
43          class(s_bar) :: a

I don't know if I got it across...

> The patch actually gives a few warnings:

Ok, thanks. I always use bootstrap and it works but I never look at
the compile result (unless it doesn't compile...)

Reply via email to