www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19384] New: Address of stack temporary is returned

https://issues.dlang.org/show_bug.cgi?id=19384

          Issue ID: 19384
           Summary: Address of stack temporary is returned
           Product: D
           Version: D2
          Hardware: x86_64
                OS: All
            Status: NEW
          Severity: critical
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: mrsmith33 yandex.ru

opIndex function returns address of stack local temporary instead of this

Reduced code:
---
void main() {
        Vec preds = Vec(0xDEAD);
        void* ptr1 = &preds;
        void* ptr2 = &preds[0];
        assert(ptr1 == ptr2);
}

struct Vec {
        uint item;

        ref uint opIndex(size_t index) {
                return item;
                // commenting next line removes bug
                foreach(ref val; range()) return val;
                assert(false);
        }
}

struct range {
        int opApply(scope int delegate(ref uint) dg) { return 0; }
}
---

Assembly without comment:
---
        ref uint opIndex(size_t index)
push        rbp  
mov         rbp,rsp  
sub         rsp,30h  
mov         qword ptr [this],rcx  
mov         qword ptr [index],rdx  
        {
                return item;
mov         rax,qword ptr [this]  
mov         qword ptr [__result],rax  
mov         qword ptr [rbp-28h],rax  // result is stored on stack
lea         rax,[rbp-28h]            // address of stack is returned instead of
value from stack
                // commenting next line fixes bug
                foreach(ref val; range()) return val;
                assert(false);
        }
mov         rsp,rbp  
pop         rbp  
ret  
---


Assembly with comment:
---
        ref uint opIndex(size_t index)
push        rbp  
mov         rbp,rsp  
mov         qword ptr [this],rcx  
mov         qword ptr [index],rdx  
        {
                return item;
mov         rax,qword ptr [this]  
                // commenting next line fixes bug
                //foreach(ref val; range()) return val;
                assert(false);
        }
pop         rbp  
ret  
---

Tested on windows and on linux (https://run.dlang.io/is/7dqb1T)

--
Nov 09 2018