You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SILGen: Fix inconsistency between vtable layout and vtable entry emission.
As part of the criteria to determine whether a method override requires a new
vtable entry in addition to overriding the base class's vtable entry for the
method, we compare the visibility of the base class to that of the derived
class, since if further subclasses of the derived class cannot see the original
base class's method descriptor, they would not be able to directly override its
vtable entry.
However, there was a subtle inconsistency in our checks in two different
places: `NeedsNewVTableEntryRequest::evaluate` compared the visibility of the
derived method to its immediate override method, whereas
`SILGenModule::emitVTableMethod` compared visibility with the ultimate base
method that originated the vtable entry in question. Internal imports create
a situation where this leads to inconsistent answers, causing us to emit
a vtable thunk but without a corresponding new vtable entry, causing the thunk
to become self-recursive (rdar://147360093). If the base class is in a separate
module:
```
// Module1
open class Base {
public required init() {}
}
```
and an intermediate class inherits that base class, it must `public import`
the module in the file defining the class to do so:
```
// Module2
public import Module1
open class MidDerived: Base { }
```
However, another file in the same module can further inherit that class, but
with only an `internal import` of the base module:
```
// Also Module2
import Module1
open class MostDerived: MidDerived { }
```
The implicit `init()` is `public` in each class, but from the perspective of
`MostDerived.init`, `Base.init` is `internal` because of the import. However,
the fact that its immediate parent is `public` should be sufficient evidence
that its original definition had visibility to `Base`, so no thunk should
be necessary.
0 commit comments