https://issues.dlang.org/show_bug.cgi?id=2013
--- Comment #3 from Kenji Hara <[email protected]> --- The problem is in both dmd and druntime code. For the class/interface hierarchy: interface IA { ... } interface IB : IA { ... } interface IC : IB { } interface ID : IA, IC { ... } class C : ID { ... } The layout of pointer to vtbls in the class C instance object is: (IA) IB IA, IC C : ID ---------------------- 0 n n+ptrsize // Note: n is the size of __vtbl + __monitor + sum of C field sizes. // It's 8 with -m32. Currently dmd generates following tree of `object.Interface` structs to represent the hierarchy: +-> CI(IA).interfaces[] == [] | A | +-------------------------+ | | | CI(IB).interfaces[] == [CI(IA)/0] | A | +-------------------------+ | | | CI(IC).interfaces[] == [CI(IB)/0] | A | +---------------------------+----------+ | | | +----------------------+ | | | | | CI(ID).interfaces[] == [CI(IA)/0, CI(IC)/0] | A | +----------------------+ +----------+ | | CI(C).interfaces[] == [CI(ID)/n, CI(IC)/n+ptrsize] // Note: CI(X) == ClassInfo(X) == typeid(X).info // CI(X)/num --> num == object.Interface.offset For the cast from IA to IB, druntime once downcast IA to Object, then calculate offset from Object(== C) to IB. It's handled by _d_interface_cast(), _d_dynamic_cast(), and _d_isbaseof2() functions in druntime/src/rt/_cast.d. The problem is in _d_isbaseof2(). It should return n+ptrsize for the cast from Object to IB, but while the iteration of above thee by breadth-first, it incorrectly returns n. ------- The way to fix the issue: 1. Fix compiler-generated Interfaces[] tree 2. Fix _d_isbaseof2() function to calculate correct offset. --
