Bug 2061 – wrong vtable call with multiple interface inheritance

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2008-04-30T11:42:00Z
Last change time
2014-03-01T00:36:22Z
Keywords
patch, wrong-code
Assigned to
bugzilla
Creator
schveiguy

Attachments

IDFilenameSummaryContent-TypeSize
367issue2061.patchThis patch should fix the issue.text/plain325

Comments

Comment #0 by schveiguy — 2008-04-30T11:42:03Z
This might be related to http://d.puremagic.com/issues/show_bug.cgi?id=1978 I added Frank and Lars to the CC in case they are interested. Basically, I think it has to do with a class implementing two interfaces that inherit from the same base interface. This might be a minimal example: extern(C) int printf(char*,...); interface A(V) { int foo(); } interface B(K, V) : A!(V) { alias A!(V).foo foo; // needed or else A isn't examined to resolve foo() int foo(int x); } interface C(K, V) : B!(K, V) { } interface D(K, V) : A!(V), C!(K, V) { alias C!(K, V).foo foo; // needed or else A is used to resolve foo int bar(); } class E(K, V) : C!(K, V) { int foo() {printf("foo\n"); return 0;} int foo(int x) {printf("foo(int)\n"); return 0;} int bar() {printf("bar\n"); return 0;} } void main() { C!(uint, uint) c = new D!(uint, uint); c.foo(); c.foo(0); c.bar(); } outputs: foo bar bar The following change to interface D seems to resolve the issue: interface D(K, V) : C!(K, V), A!(V) { int bar(); } However, there might be cases where this kind of solution is not possible.
Comment #1 by schveiguy — 2008-11-24T08:46:43Z
sheesh, I think I have messed up the example. Please replace the definition for class E, and the main function with this: class E(K, V) : D!(K, V) { int foo() {printf("foo\n"); return 0;} int foo(int x) {printf("foo(int)\n"); return 0;} int bar() {printf("bar\n"); return 0;} } void main() { D!(uint, uint) d = new E!(uint, uint); d.foo(); d.foo(0); d.bar(); }
Comment #2 by schveiguy — 2008-12-09T11:43:55Z
Bumped into this again, with a simpler inheritance tree. extern(C) int printf(char*,...); interface A { char a(); } interface B { char b(); } interface C : A, B { char c(); } interface D { char d(); } interface E : C, D { char e(); } class Foo : E { char a() { return('a'); } char b() { return('b'); } char c() { return('c'); } char d() { return('d'); } char e() { return('e'); } } void main() { auto foo = new Foo; E e = foo; D d = foo; C c = foo; B b = foo; A a = foo; printf("Foo: %c %c %c %c %c\n", foo.a, foo.b, foo.c, foo.d, foo.e); printf("A: %c\n", a.a); printf("B: %c\n", b.b); printf("C: %c %c %c\n", c.a, c.b, c.c); printf("D: %c\n", d.d); printf("E: %c %c %c %c %c\n", e.a, e.b, e.c, e.d, e.e); } outputs: Foo: a b c d e A: a B: b C: a b c D: d E: a a c d e Note the incorrect E line. If I swap around E's base interfaces, so E now becomes: interface E : D, C { char e(); } Now the E line is still wrong: Foo: a b c d e A: a B: b C: a b c D: d E: d b c d e Marking as a blocker. I don't know how to work around this.
Comment #3 by rsinfu — 2009-05-14T20:50:40Z
*** Issue 2758 has been marked as a duplicate of this issue. ***
Comment #4 by rsinfu — 2009-05-14T21:10:49Z
Created attachment 367 This patch should fix the issue. There is a typo in class.c. The compiler generates wrong vtable due to the typo.
Comment #5 by schveiguy — 2009-05-15T06:56:20Z
Which compiler version is your patch against? According to the changelog, 1.045 fixed this issue. I haven't had time to test it yet, you may want to compare your patch against that fix.
Comment #6 by bugzilla — 2009-05-15T12:14:26Z
Fixed dmd 1.045 and 2.030