nickitat wrote:

Thanks for your comments. AFAIK, the general problem that prevents a lot of 
devirtualization currently is that we should assume that code like this exists 
in the program:

``` cpp
#include <new>
#include <cstdio>

struct Base {
    virtual void hello() { printf("Base\n"); }
    virtual ~Base() = default;
};

struct Derived : Base {
    virtual void hello() override { printf("Derived\n"); }
};

static_assert(sizeof(Base) == sizeof(Derived)); // same layout

void clobber(Base* p) {
    p->~Base();                  // explicitly destroy the Base object
    ::new (p) Derived();         // construct a Derived in the same storage
    // vptr now points to Derived's vtable
}

int main() {
    alignas(Derived) unsigned char buf[sizeof(Derived)];
    Base* p = ::new (buf) Base();

    p->hello();   // "Base"
    clobber(p);
    p->hello();   // "Derived"

    p->~Base();   // calls ~Derived() via vtable — correct
}
```

I.e., a simple fact that we have a `T*` and that `T` is final or whatever does 
not guarantee anything by itself. This is why the current implementation is 
able to devirtualize when it can find the relevant store of vptr:

https://github.com/llvm/llvm-project/blob/8e702735090388a3231a863e343f880d0f96fecb/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp#L709-L712

And a case like this works in the current clang:

``` cpp
void h() { 
    Impl impl; // here is the traceable vptr store
    impl.foo();
}
```

But not the case from the description. So, I don't aim for a really generic 
solution here. Rather, I'd like to extend the current logic tracking vptr 
stores to include `static_cast` as another source of a guarantee on the dynamic 
type.

How to properly propagate this knowledge from the `static_cast` to all 
subsequent calls is another good question. Probably with alias analysis or some 
clever invariant groups that were described 
[here](https://youtu.be/Dt4UehzzcsE?si=t-OPPNrz8ogCYUBN). For now I've added a 
simple AA-based solution. 

https://github.com/llvm/llvm-project/pull/185087
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to