Bug 19192 – [wrong-code] [crashes] Covariant method interface <- abstract class <- class hierarchies

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-08-26T13:24:50Z
Last change time
2021-04-09T10:48:53Z
Keywords
pull, wrong-code
Assigned to
No Owner
Creator
Puneet Goel

Comments

Comment #0 by puneet — 2018-08-26T13:24:50Z
tested with DMD 2.081.2 and with LDC 1.10 $ rdmd covariant.d [] $ rdmd -version=COVARIANT covariant.d [1635151715, 1851877746, 1631727220, 1965564274, 1735290732, 774462811, 7496002, 0, 4802768, 0, 4492600, 0, 4492620, 0, 4492632, 0, 4492772, 0, 4448724, 0, 4448744, 0, 0, 0, 4505724, 0, 0] [email protected](55): Assertion failure // covariant.d interface Foo { int[] vars(); Foo troll(); } class Frop: Foo { int[] vars() { assert(false); } Foo troll() { assert(false); } } abstract class Barbee : Foo {} class Bar(V): Barbee { Barber!(V) _barber; this(Barber!(V) barber) { _barber = barber; } int[] vars() { return _barber.vars; } version (COVARIANT) alias COVARTYPE = typeof(this); else alias COVARTYPE = Foo; COVARTYPE troll() { return _barber.troll()[0]; } } class Barber(V) { Bar!(V)[] _elems; int[] vars() { return []; } auto troll() { return this; } void build(size_t v) { _elems.length = v; for (size_t i; i!=v; ++i) _elems[i] = new Bar!(V)(this); } Bar!(V) opIndex(Foo indx) { return new Bar!(V)(this); } Bar!(V) opIndex(size_t n) { build(n+1); return _elems[n]; } } void main() { import std.stdio; auto barber = new Barber!(ulong[])(); auto frop = new Frop(); Foo foo = barber[frop]; Foo fool = foo.troll(); auto ll = fool.vars; writeln(ll); assert (ll.length == 0); }
Comment #1 by ag0aep6g — 2018-08-27T22:41:15Z
Reduced: ---- interface Foo { Foo troll(); } abstract class Barbee : Foo {} class Bar : Barbee { Bar troll() { return this; } } void main() { Foo foo = new Bar; assert(foo is foo.troll); /* Fails. Should pass. */ } ----
Comment #2 by iamthewilsonator — 2018-09-28T10:54:55Z
This appears to be a missing an offset somewhere. printf("%p", foo); //0x7fe552a44010 printf("%p", foo.troll); //0x7fe552a44000 It fails also with LDC so the problem is likely a missed cast in the frontend. Note that: interface Foo { Foo troll(); } abstract class Barbee : Foo {} class Bar : Barbee { /*Bar*/ Foo troll() { return this; } } Works. and interface Foo { Foo troll(); } abstract class Barbee : Foo {} //alias Barbee = Foo; class Bar : Barbee { Bar troll() { return this; } } void main() { Foo foo = new Bar; auto troll = cast(Barbee)foo.troll; // ICE's assert(foo is troll); } ICE's
Comment #3 by iamthewilsonator — 2018-09-28T11:04:17Z
Sorry that segfaults not ICE's
Comment #4 by dlang-bot — 2021-03-24T08:42:28Z
@puneet created dlang/dmd pull request #12302 "Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <…" fixing this issue: - Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <- abstract class <- class hierarchies While analyzing covariant methods, dmd semantic analyzer searched for immediate interfaces of the class that may have a vtbl entry matching the method. This failed for possible scenarios where the covariant method may be declared in an interface inheritance of an abstract base class. The fix adds a for loop that iterates over the base classes to find the relevant interface with matching vtbl entry. https://github.com/dlang/dmd/pull/12302
Comment #5 by dlang-bot — 2021-03-24T12:39:25Z
dlang/dmd pull request #12302 "Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <…" was merged into stable: - a7427a67219ed0d8095e0e545b0d73f9e8237906 by Puneet Goel: Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <- abstract class <- class hierarchies While analyzing covariant methods, dmd semantic analyzer searched for immediate interfaces of the class that may have a vtbl entry matching the method. This failed for possible scenarios where the covariant method may be declared in an interface inheritance of an abstract base class. The fix adds a for loop that iterates over the base classes to find the relevant interface with matching vtbl entry. https://github.com/dlang/dmd/pull/12302
Comment #6 by dlang-bot — 2021-04-09T10:48:53Z
dlang/dmd pull request #12408 "Merge stable into master" was merged into master: - df37bc2c2f03180196ceccc64a4f653ad9807f0d by Puneet Goel: Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <… (#12302) * Fix issue 19192 - [wrong-code] [crashes] Covariant method interface <- abstract class <- class hierarchies While analyzing covariant methods, dmd semantic analyzer searched for immediate interfaces of the class that may have a vtbl entry matching the method. This failed for possible scenarios where the covariant method may be declared in an interface inheritance of an abstract base class. The fix adds a for loop that iterates over the base classes to find the relevant interface with matching vtbl entry. https://github.com/dlang/dmd/pull/12408