www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5071] New: passing value by ref to a function with an inner dynamic closure results in a wrong code

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

           Summary: passing value by ref to a function with an inner
                    dynamic closure results in a wrong code
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: 2korden gmail.com


--- Comment #0 from Koroskin Denis <2korden gmail.com> 2010-10-18 09:44:59 PDT
---
Here is a test case:

import std.stdio;

void passObject(ref char c, bool dummy)
{
}

void passClosure(void delegate() dg)
{
}

void test(ref char c, bool dummy = false) {
    writeln("inside c=", c, " (", cast(int)c, ") &c=", &c);

    void closure() {
        passObject(c, dummy);
    }

    passClosure(&closure);
}

void main()
{
    //* Test one (c is on heap)
    char* c = new char;
    *c = 'a';

    writeln("outside c=", *c, " (", cast(int)*c, ") &c=", c);
    test(*c, true);

    /*/ Test two (c is on stack)
    char c = 'a';
    writeln("outside c=", c, " (", cast(int)c, ") &c=", &c);
    test(c);
    //*/
}

Test one output:
outside c=a (97) &c=12B2E40
inside c=  (0) &c=12B0140

Test two output:
outside c=a (97) &c=12FE54
object.Error: Access Violation

Note that passing by pointer instead works fine:

outside c=a (97) &c=582E40
inside c=a (97) &c=582E40

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 18 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5071


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla digitalmars.com
           Severity|normal                      |critical


--- Comment #1 from Walter Bright <bugzilla digitalmars.com> 2010-10-18
11:05:58 PDT ---
Priority bumped up because newbies run into it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 18 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5071


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |patch
                 CC|                            |clugdbug yahoo.com.au


--- Comment #2 from Don <clugdbug yahoo.com.au> 2010-10-19 08:42:34 PDT ---
REDUCED TEST CASE:
void doNothing() {}

void bug5071(short d, ref short c) {
   assert(c==0x76);

    void closure() {
        auto c2 = c;
        auto d2 = d;
        doNothing();
    }
    auto useless = &closure;    
}

void main()
{
   short c = 0x76;
   bug5071(7, c);
}

PATCH: toir.c, FuncDeclaration::buildClosure(), line 648.
When it copies the parameters into the closure, it correctly recognizes that
ref params are just pointers. But, it needs to do the same thing when working
out what offsets they are at.

#if DMDV2
            if (v->storage_class & STClazy)
            {
                /* Lazy variables are really delegates,
                 * so give same answers that TypeDelegate would
                 */
                memsize = PTRSIZE * 2;
                memalignsize = memsize;
                xalign = global.structalign;
            }
+            else if (v->isRef() || v->isOut())
+            {    // reference parameters are just pointers
+                memsize = PTRSIZE;
+                memalignsize = memsize;
+                xalign = global.structalign;
+            }
            else
#endif
            {
                memsize = v->type->size();
                memalignsize = v->type->alignsize();
                xalign = v->type->memalign(global.structalign);
            }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 19 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5071


Walter Bright <bugzilla digitalmars.com> changed:

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


--- Comment #3 from Walter Bright <bugzilla digitalmars.com> 2010-10-20
01:16:13 PDT ---
http://www.dsource.org/projects/dmd/changeset/724

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