From bbd22804313fa37fe2848b7f3bc45f83f4ea8db8 Mon Sep 17 00:00:00 2001 From: Martin Nowak Date: Thu, 29 Dec 2016 14:12:12 +0100 Subject: [PATCH] fix Issue 16980 - wrong interface called - ensure that class/interface size is finalized before determining the interface offsets --- src/dclass.d | 10 ++++++++-- test/runnable/test16980.d | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 test/runnable/test16980.d diff --git a/src/dclass.d b/src/dclass.d index fcdf7df94cd..167f4dbcb58 100644 --- a/src/dclass.d +++ b/src/dclass.d @@ -1876,9 +1876,15 @@ extern (C++) final class InterfaceDeclaration : ClassDeclaration //printf("\tX base %s\n", b.sym.toChars()); if (this == b.sym) { - //printf("\tfound at offset %d\n", b.offset); if (poffset) - *poffset = b.offset; + { + // Need to determine correct offset if needed. + // https://issues.dlang.org/show_bug.cgi?id=16980 + cd.size(loc); + // HACK: using OFFSET_RUNTIME as error placeholder + *poffset = cd.sizeok == SIZEOKdone ? b.offset : OFFSET_RUNTIME; + } + // printf("\tfound at offset %d\n", b.offset); return true; } if (isBaseOf(b, poffset)) diff --git a/test/runnable/test16980.d b/test/runnable/test16980.d new file mode 100644 index 00000000000..ea94d2219a5 --- /dev/null +++ b/test/runnable/test16980.d @@ -0,0 +1,22 @@ +// https://issues.dlang.org/show_bug.cgi?id=16980 +interface A { void foo(); } +interface B { void bar(); } +interface AB : A, B {} +class C : AB { + void foo() { assert(false, "Must never be called!"); } + void bar() {} +} + +struct T() { + AB ab; + ~this() { + ab.bar(); // uses wrong vtable + } +} + +T!() tinst; // triggers semantic3 of dtor from Module::semantic(1) + +void main() +{ + auto dst = T!()(new C); +}