On Thursday, 29 November 2012 at 12:38:03 UTC, Dan wrote:
On Thursday, 29 November 2012 at 07:59:02 UTC, Maxim Fomin wrote:

This doesn't look like assembly for previous source. Please provide the source for which you have assembly and tell which dmd options do you use.

Well, I'm using the latest dmd (from the trunk), phobos, druntime, so I could build and step through.


This is version generated by rdmd -version=bug --force --build-only -g -w -property. The only difference between this and yours is in <+71>.

<+00>:    push   %rbp
<+01>:    mov    %rsp,%rbp
<+04>:    sub    $0x38,%rsp
<+08>:    push   %rbx
// push 3 as a pkey, -0x30(%rbp) is 3
<+09>:    mov    $0x3,%eax
<+14>:    mov    %eax,-0x30(%rbp)
<+17>:    lea    -0x30(%rbp),%rcx
// push valuesize
<+21>:    movabs $0x8,%rdx
// push keyti
<+31>:    movabs $0x430f50,%rsi
// push map address, it is tls object
<+41>:    mov    %fs:0x0,%rdi
<+50>:    add    0x21e22f(%rip),%rdi        # 0x636fb0
// call, keyti=8, aa=&map, valuesize=8, pkey=3
<+57>:    callq  0x419140 <_aaGetX>
// store return value in -0x28(%rbp)
<+62>:    mov    %rax,-0x28(%rbp)
// check array bounds
<+66>:    test   %rax,%rax
<+69>:    jne    0x418d99 <_Dmain+81>
<+71>:    mov    $0x13,%edi
<+76>:    callq  0x418e28 <_D4main7__arrayZ>
// constructing S rhs for opAssign
<+81>:    movabs $0x2a,%rax
<+91>:    mov    %rax,-0x18(%rbp) // rhs
<+95>:    mov    %rax,%rsi
// making this from -0x20(%rbp), but it was stored in -0x28(%rbp)
<+98>:    lea    -0x20(%rbp),%rdi
// opAssign loads this from %rdi
<+102>:   callq  0x418ce0 <_D4main1S8opAssignMFS4main1SZv>
// replace content in -0x28(%rbp) by -0x20(%rbp)
<+107>:   mov    -0x20(%rbp),%rcx
<+111>:   mov    -0x28(%rbp),%rdx
<+115>:   mov    %rcx,(%rdx)
// load previously created object
<+118>:   movl   $0x3,-0x10(%rbp)
<+125>:   lea    -0x10(%rbp),%rcx
<+129>:   movabs $0x8,%rdx
<+139>:   movabs $0x430f50,%rsi
<+149>:   mov    %fs:0x0,%rax
<+158>:   mov    0x21e1c3(%rip),%rbx        # 0x636fb0
<+165>:   mov    (%rax,%rbx,1),%rdi
<+169>:   callq  0x4192b8 <_aaGetRvalueX>
// store pointer to existed object
<+174>:   mov    %rax,-0x8(%rbp)
// check array bounds
<+178>:   test   %rax,%rax
<+181>:   jne    0x418e09 <_Dmain+193>
<+183>:   mov    $0x14,%edi
<+188>:   callq  0x418e28 <_D4main7__arrayZ>
// load x member
<+193>:   mov    -0x8(%rbp),%rcx
<+197>:   mov    (%rcx),%rsi
<+200>:   movabs $0x430ac0,%rdi
<+210>:   xor    %eax,%eax
<+212>:   callq  0x4188e0 <printf@plt>
<+217>:   xor    %eax,%eax
<+219>:   pop    %rbx
<+220>:   leaveq
<+221>:   retq
End of assembler dump.

Main stack frame looks follows:
-0x30(%rbp):-0x28(%rbp) 3 as a pkey arg to _aaGetX
-0x28(%rbp):-0x20(%rbp) pointer to S allocated by _aaGetX
-0x20(%rbp):-0x18(%rbp) uninitialized struct - "this" ptr
-0x18(%rbp):-0x10(%rbp) constructed struct passed as rhs to opAssign
-0x10(%rbp):-0x08(%rbp) 3 as a pkey arg to _aaGetRvalueX
-0x08(%rbp):-0x00(%rbp) pointer to S returned from _aaGetRvalueX

It seems that dmd allocates space for two structs, one non-initialized, second initialized, issues call to druntime, then places a call to opAssign with non-initialized as "this" object with initialized as rhs argument, then writes content on non-initialized to allocated by druntime. So, this looks like a codegen bug.

By the way, if the code is compiled with command "dmd main -g -release -noboundscheck -version=bug", opAssign call is placed before calling _aaGetX.

Reply via email to