Fix: reverts the change in r188 which causes the bug
text/plain
440
Comments
Comment #0 by svanleent — 2008-02-16T15:16:59Z
On the x86-64 platform, downcasting from an interface towards it's original object, appears to throw up segmentation fault. This is a test which get's it to go wrong (the version of GDC used was revision 199):
module test_2008_02_13;
import tango.io.Console;
public interface A {
void foo();
}
public interface B {
void bar();
}
public interface C : B {}
public interface D : A, C {
void foobar();
}
public interface E : D {}
public interface F : E {}
public interface G : F {}
public class AB : G {
void foo() {
Cout("Foo").newline;
}
void bar() {
Cout("Bar").newline;
}
void foobar() {
Cout("FooBar").newline;
}
}
/// Upcast Tests
void upcastTests(AB ab) {
Cout("---Start Upcast Tests---").newline;
if(cast(A)ab) {
auto a = cast(A)ab;
a.foo(); // Should print Foo
}
if(cast(B)ab) {
auto b = cast(B)ab;
b.bar(); // Should print Bar
}
if(cast(C)ab) {
auto c = cast(C)ab;
c.bar(); // Should print Bar
}
if(cast(D)ab) {
auto d = cast(D)ab;
d.foobar(); // Should print FooBar
}
if(cast(E)ab) {
auto e = cast(E)ab;
e.foobar(); // Should print FooBar
}
if(cast(F)ab) {
auto f = cast(F)ab;
f.foobar(); // Should print FooBar
}
if(cast(G)ab) {
auto g = cast(G)ab;
g.foobar(); // Should print FooBar
}
Cout("---End Upcast Tests---").newline;
}
/// Downcast Tests
void downcastTests(A a) {
Cout("---Start Downcast Tests---").newline;
a.foo(); // Should print Foo
// Segfaults from here onwards
if(cast(B)a) {
auto b = cast(B)a;
b.bar();
}
if(cast(C)a) {
auto c = cast(C)a;
c.bar();
}
if(cast(D)a) {
auto d = cast(D)a;
d.foobar();
}
if(cast(E)a) {
auto e = cast(E)a;
e.foobar();
}
if(cast(F)a) {
auto f = cast(F)a;
f.foobar();
}
if(cast(G)a) {
auto g = cast(G)a;
g.foobar();
}
if(cast(AB)a) {
auto ab = cast(AB)a;
ab.foobar();
}
Cout("---End Downcast Tests---").newline;
}
void main(char[][] args) {
auto ab = new AB();
ab.foo(); // prints Foo
ab.bar(); // prints Bar
upcastTests(ab);
downcastTests(ab);
}
Comment #1 by svanleent — 2008-02-16T15:17:41Z
Created attachment 227
Test case
Comment #2 by svanleent — 2008-02-20T14:52:19Z
Created attachment 228
Test case made by sean
This gives a bit more verbose output of the problem area of the interfaces on the x86-64 system.
Comment #3 by e-t172 — 2008-02-27T04:10:37Z
Created attachment 229
Fix: reverts the change in r188 which causes the bug
I've done some regression tests. The bug is introduced by r188. I narrowed it down to a very small change in dmd/toobj.c.
Attached patch reverts this change. This seems to have fixed the bug.
Before the patch:
$ ./cast_test
Supported interfaces:
tango.io.model.IConduit.IConduit
tango.io.model.IConduit.OutputStream
tango.io.model.IConduit.ISelectable
Attempted cast:
_d_dynamic_cast(o = 0x2b31b3111e40, c = 'tango.io.model.IBuffer.Buffered')
oc: tango.sys.Pipe.PipeConduit
oc: tango.io.DeviceConduit.DeviceConduit
oc: tango.io.Conduit.Conduit
oc: tango.io.model.IConduit.IConduit
Segmentation fault
After the patch:
$ ./cast_test
Supported interfaces:
tango.io.model.IConduit.IConduit
tango.io.model.IConduit.OutputStream
tango.io.model.IConduit.ISelectable
Attempted cast:
_d_dynamic_cast(o = 0x2b20a852ee40, c = 'tango.io.model.IBuffer.Buffered')
oc: tango.sys.Pipe.PipeConduit
oc: tango.io.DeviceConduit.DeviceConduit
oc: tango.io.Conduit.Conduit
oc: tango.io.model.IConduit.IConduit
oc: tango.io.model.IConduit.InputStream
oc: tango.io.model.IConduit.IOStream
oc: tango.io.model.IConduit.OutputStream
oc: tango.io.model.IConduit.IOStream
oc: tango.io.model.IConduit.OutputStream
oc: tango.io.model.IConduit.IOStream
oc: tango.io.model.IConduit.ISelectable
oc: object.Object
result = (nil)
Comment #4 by svanleent — 2008-02-27T13:59:36Z
When looking at toobj.c from the DMD2 release, I notice that the order is different:
dti32(&dt, 4 | isCOMinterface(), true);
instead of (DMD1):
dti32(&dt, 4 | com, isCOMinterface());
perhaps this is the real error
Comment #5 by svanleent — 2008-03-06T13:15:41Z
Just to make it clear it can, the line:
dti32(&dt, 4 | com, isCOMinterface());
should become:
dti32(&dt, 4 | isCOMinterface(), true);
Sjoerd
Comment #6 by dvdfrdmn — 2008-04-17T22:22:12Z
Fixed in release 0.25 / svn 212
Comment #7 by fvbommel — 2008-12-22T18:57:44Z
*** Bug 2536 has been marked as a duplicate of this bug. ***