This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/46043] New: attribute to mark virtual methods that can't be further overriden so they can be devirtualized


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46043

           Summary: attribute to mark virtual methods that can't be
                    further overriden so they can be devirtualized
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: zsojka@seznam.cz


In some scenarios, there is one abstract class declaring virtual methods with
several derived classes, all of them overriding those methods. (at least in
OpenTTD that happens often) The important point is that there are no further
derived classes from those. For example:

struct A {
  virtual void f1() = 0;
  virtual void f2() = 0;
  virtual void f3() { ... this->f1(); this->f2(); ... }
};

struct B : A {
  virtual void f1();
  virtual void f2() { ... this->f1(); ... }
};

struct C : A {
  virtual void f1();
  virtual void f2();
  virtual void f3() { ... this->f1(); this->f2(); ... }
};

struct D : A {
  virtual void f1();
  virtual void f2();
};

If there was an information that there are no classes derived from B,C,D, it
would allow many devirtualizations.
One idea I could come with would be omitting the "virtual" keyword causing the
method to lose its "virtual" status. But that would break a lot of existing
code.
Second idea is using an attribute for that. While searching for this issue I
found java uses "final" keyword for this purpose (or at least it seems to me
so), so I will use attribute "final" in the following example:

struct A {
    virtual void f1();
    virtual void f2();
    virtual void f3();
};

/* f1() can't be further overriden */
struct B : A {
    virtual void f1() __attribute__((final));
};

/* no virtual method can further be overriden */
struct C : A {
    virtual void f3();
} __attribute__((final));

struct D : C {
    virtual void f4();
};

struct E : D {
} __attribute__((final));

void foo(struct C *c, struct D *d, struct E *e)
{
    c->f1(); /* c->B::f1() */
    c->f2(); /* c->A::f2() */
    c->f3(); /* c->C::f3() */
    d->f1(); /* d->B::f1() */
    d->f4(); /* not known at compile-time */
    e->f1(); /* e->B::f1() */
    e->f4(); /* e->D::f4() */
}

/* The following results in compile errors */
struct F : D {
    virtual void f1(); /* error */
    virtual void f2(); /* error */
    virtual void f3(); /* error */
    virtual void f4();
};

I searched the bugzilla for this issue and found none open. Given this idea is
quite simple and the gain can be high, there might be something I overlooked.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]