[Issue 2013] interface to interface dynamic cast is incorrect in some cases
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sat Jul 18 06:02:30 PDT 2015
https://issues.dlang.org/show_bug.cgi?id=2013
--- Comment #3 from Kenji Hara <k.hara.pg at gmail.com> ---
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.
--
More information about the Digitalmars-d-bugs
mailing list