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

            Bug ID: 65143
           Summary: [C++11] missing devirtualization for virtual base in
                    "final" classes
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: balakrishnan.erode at gmail dot com

When a class is marked final, it can devirtualize access to all base classes as
its layout is known. This is missing in gcc. 

struct A
{
  int i();
};

struct B : public virtual A
{
  int get()
  {
    return A::i() + 1;
  }
};

struct C final : public B
{
  int get()
  {
    return A::i() + 2;
  }
};

int foo(C& c)
{  
  return c.get(); // Need not go via vtable pointer as class C is final
}

int foo(B& b2)
{
  return b2.get(); // This has to go via vtable as most derived class can
change the location of A
}

Assembly: Both do virtual dispatch

foo(C&):
    subq    $8, %rsp
    movq    (%rdi), %rax
    addq    -24(%rax), %rdi
    call    one::A::i()
    addq    $8, %rsp
    addl    $2, %eax
    ret
foo(B&):
    subq    $8, %rsp
    movq    (%rdi), %rax
    addq    -24(%rax), %rdi
    call    one::A::i()
    addq    $8, %rsp
    addl    $1, %eax
    ret

Complete example:
gcc: http://goo.gl/U4KEvj
clang: http://goo.gl/PpQCkd  -- Clang does this optimization

Reply via email to