Thread overview
[Issue 3634] New: return value not passed to out contracts of private methods
Dec 19, 2009
Witold Baryluk
Dec 19, 2009
Witold Baryluk
Dec 19, 2009
Witold Baryluk
Jun 07, 2010
Don
December 19, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3634

           Summary: return value not passed to out contracts of private
                    methods
           Product: D
           Version: 2.036
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: baryluk@smp.if.uj.edu.pl


--- Comment #0 from Witold Baryluk <baryluk@smp.if.uj.edu.pl> 2009-12-18 22:37:44 PST ---
This code failes, but it should pass.

class A {
    this() {
        x_ = 10;
    }
private:
    uint x_;

    uint x()
    out(ret) {
        assert(ret == 10); // fails  // line 10
        assert(ret == x_); // fails
    }
    body {
        return x_;
    }
}

import std.stdio;

void main() {
    auto a = new A();
    writefln("%d", a.x());
}

$ dmd2 -debug a.d; ./a
 core.exception.AssertError@t(10): Assertion failure
$

When I change x() method to 'public' problems dissaper.


Here is dissambled code

        assume  CS:.text._D1t1A1xMFZk
_D1t1A1xMFZk:
                push    EBP
                mov     EBP,ESP
                sub     ESP,0Ch
                add     EAX,8
                mov     ECX,[EAX]
                mov     -8[EBP],ECX
                mov     -0Ch[EBP],EAX
                mov     EAX,0Ah
                call    near ptr _D1t8__assertFiZv@PC32
                mov     EDX,-0Ch[EBP]
                cmp     dword ptr [EDX],0
                je      L2D
                mov     EAX,0Bh
                call    near ptr _D1t8__assertFiZv@PC32
L2D:            mov     EAX,-8[EBP]
                leave
                ret
                nop
                nop
.text._D1t1A1xMFZk      ends


Also without "-debug" switch the same code is generated.
If i comment a assert statments (or don't use ret), method properly returns
value to callee.


In release mode it works correclty (but contracts are called):

.text._D1t1A1xMFZk      segment
        assume  CS:.text._D1t1A1xMFZk
_D1t1A1xMFZk:
                push    EBP
                mov     EBP,ESP
                sub     ESP,4
                mov     EAX,8[EAX]
                leave
                ret
                nop
.text._D1t1A1xMFZk      ends

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 19, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3634



--- Comment #1 from Witold Baryluk <baryluk@smp.if.uj.edu.pl> 2009-12-18 22:59:08 PST ---
Original code (with "private") fails also with "-O", "-O -inline", and many
others.

Here is simplified case:

class A {
    this() {
        x_ = 0x40;
    }
private:
    uint x_;
//public:
    uint x()
    out(ret) {
        pppp(ret);
    }
    body {
        return x_;
    }
}
import std.stdio;
void main() {     auto a = new A(); }
void pppp(uint xxx) {    xxx ++; }

.text._D1t1A1xMFZk      segment
        assume  CS:.text._D1t1A1xMFZk
_D1t1A1xMFZk:
                push    EBP
                mov     EBP,ESP
                sub     ESP,8
                mov     ECX,8[EAX]   // move field x_ to the ECX register
                mov     -8[EBP],ECX  // save ret in EBP[-8]
                xor     EAX,EAX       // set ret = 0
                call    near ptr _D1t4ppppFkZv@PC32 // call pppp(EAX)
                mov     EAX,-8[EBP] // restore ret after return from ppp
                leave
                ret   // return
.text._D1t1A1xMFZk      ends

When changed to "public":

.text._D1t1A1xMFZk      segment
        assume  CS:.text._D1t1A1xMFZk
_D1t1A1xMFZk:
                push    EBP
                mov     EBP,ESP
                sub     ESP,8
                mov     -4[EBP],EAX
                call    near ptr _D9invariant12_d_invariantFC6ObjectZv@PC32
                mov     EAX,-4[EBP]
                mov     ECX,8[EAX]
                mov     -8[EBP],ECX
                lea     EDX,-8[EBP]
                push    EDX
                call    near ptr _D1t1A1xMFZk8__ensureMFKxkZv@PC32
                mov     EAX,-8[EBP]
                leave
                ret
                nop
                nop
                nop
.text._D1t1A1xMFZk      ends
.text._D1t1A1xMFZk8__ensureMFKxkZv      segment
        assume  CS:.text._D1t1A1xMFZk8__ensureMFKxkZv
_D1t1A1xMFZk8__ensureMFKxkZv:
                push    EBP
                mov     EBP,ESP
                sub     ESP,4
                mov     ECX,8[EBP]  // take address of field x_ and put into
ECX
                mov     EAX,[ECX] // move content of field x_ into EAX
                call    near ptr _D1t4ppppFkZv@PC32 // call pppp(EAX)
                leave
                ret     4 // return
.text._D1t1A1xMFZk8__ensureMFKxkZv      ends

_D9invariant12_d_invariantFC6ObjectZv@PC32 is and Object.invariant() from base
class.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 19, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3634



--- Comment #2 from Witold Baryluk <baryluk@smp.if.uj.edu.pl> 2009-12-18 23:03:34 PST ---
Using "protected" attributed it works correctly:

.text._D1t1A1xMFZk      segment
        assume  CS:.text._D1t1A1xMFZk
_D1t1A1xMFZk:
                push    EBP
                mov     EBP,ESP
                sub     ESP,8
                mov     ECX,8[EAX]
                mov     -8[EBP],ECX
                lea     EDX,-8[EBP]
                push    EDX
                call    near ptr _D1t1A1xMFZk8__ensureMFKxkZv@PC32
                mov     EAX,-8[EBP]
                leave
                ret
                nop
                nop
.text._D1t1A1xMFZk      ends
.text._D1t1A1xMFZk8__ensureMFKxkZv      segment
        assume  CS:.text._D1t1A1xMFZk8__ensureMFKxkZv
_D1t1A1xMFZk8__ensureMFKxkZv:
                push    EBP
                mov     EBP,ESP
                sub     ESP,4
                mov     ECX,8[EBP]
                mov     EAX,[ECX]
                call    near ptr _D1t4ppppFkZv@PC32
                leave
                ret     4
.text._D1t1A1xMFZk8__ensureMFKxkZv      ends


I was first thinking this is problem with constatnt propagation, but i don't think this is good guess. Hope someone with better knowledge of backend can say something more relevant. :)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3634


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |clugdbug@yahoo.com.au
         Resolution|                            |DUPLICATE


--- Comment #3 from Don <clugdbug@yahoo.com.au> 2010-06-07 00:11:57 PDT ---
This was a regression in 2.037. Fixed in the beta of 2.047.

*** This issue has been marked as a duplicate of issue 3667 ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------