[clang] [clang] Allow devirtualisation of indirect calls to final virtual methods (PR #165341)

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 28 20:15:37 PDT 2025


ChuanqiXu9 wrote:

After I add the following, the bootstrap build and test succeeded for me:

```
    if (CGM.getCodeGenOpts().StrictVTablePointers && CXXThisValue) {
      const CXXRecordDecl *ThisRecordDecl = MD->getParent();
      bool IsPolymorphicObject = ThisRecordDecl->isPolymorphic();
      bool IsStructor = isa<CXXDestructorDecl, CXXConstructorDecl>(MD);
      bool IsFinal = ThisRecordDecl->isEffectivelyFinal();

      // A workaround for cases the base class defined virtual dtor while
      // the derived class don't offer it. Then the current implementation may
      // introduce undefined symbols as it introduce all symbols in the
      // vtable.
      bool BaseHasDtor = false;
      ThisRecordDecl->forallBases([&](const CXXRecordDecl *Base) -> bool {
        if (Base->getDestructor() && !Base->getDestructor()->isImplicit())
            BaseHasDtor = true;
  
        return true;
      });
      bool HasDtor = ThisRecordDecl->getDestructor() &&
          !ThisRecordDecl->getDestructor()->isImplicit();

      // We do not care about whether this is a virtual method, because even
      // if the current method is not virtual, it may be calling another method
      // that calls a virtual function.
      if (IsPolymorphicObject && !IsStructor && IsFinal && (!BaseHasDtor || HasDtor))
        EmitVTableAssumptionLoads(ThisRecordDecl, LoadCXXThisAddress());
    }
```

https://github.com/llvm/llvm-project/pull/165341


More information about the cfe-commits mailing list