www.digitalmars.com         C & C++   DMDScript  

D.gnu - [Issue 1844] New: Problems using dynamic cast on x86-64 platform

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844

           Summary: Problems using dynamic cast on x86-64 platform
           Product: DGCC aka GDC
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P1
         Component: glue layer
        AssignedTo: dvdfrdmn users.sf.net
        ReportedBy: svanleent gmail.com


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);

}


-- 
Feb 16 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844





------- Comment #1 from svanleent gmail.com  2008-02-16 15:17 -------
Created an attachment (id=227)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=227&action=view)
Test case


-- 
Feb 16 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844





------- Comment #2 from svanleent gmail.com  2008-02-20 14:52 -------
Created an attachment (id=228)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=228&action=view)
Test case made by sean

This gives a bit more verbose output of the problem area of the interfaces on
the x86-64 system.


-- 
Feb 20 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844





------- Comment #3 from e-t172 akegroup.org  2008-02-27 04:10 -------
Created an attachment (id=229)
 --> (http://d.puremagic.com/issues/attachment.cgi?id=229&action=view)
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)


-- 
Feb 27 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844





------- Comment #4 from svanleent gmail.com  2008-02-27 13:59 -------
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


-- 
Feb 27 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844





------- Comment #5 from svanleent gmail.com  2008-03-06 13:15 -------
Just to make it clear it can, the line:

dti32(&dt, 4 | com, isCOMinterface());

should become:

dti32(&dt, 4 | isCOMinterface(), true);

Sjoerd


-- 
Mar 06 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844


dvdfrdmn users.sf.net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED




------- Comment #6 from dvdfrdmn users.sf.net  2008-04-17 22:22 -------
Fixed in release 0.25 / svn 212


-- 
Apr 17 2008
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1844


fvbommel wxs.nl changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fvbommel wxs.nl




------- Comment #7 from fvbommel wxs.nl  2008-12-22 18:57 -------
*** Bug 2536 has been marked as a duplicate of this bug. ***


-- 
Dec 22 2008