Bug 1844 – Problems using dynamic cast on x86-64 platform

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Linux
Creation time
2008-02-16T15:16:00Z
Last change time
2015-06-09T05:15:21Z
Keywords
wrong-code
Assigned to
dvdfrdmn
Creator
svanleent

Attachments

IDFilenameSummaryContent-TypeSize
227test-2008-02-13.dTest casetext/plain1828
228testapp.dTest case made by seantext/plain2003
229gdc-interface-cast.patchFix: reverts the change in r188 which causes the bugtext/plain440

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. ***