Thread overview
[Issue 5071] New: passing value by ref to a function with an inner dynamic closure results in a wrong code
Oct 18, 2010
Koroskin Denis
Oct 18, 2010
Walter Bright
Oct 19, 2010
Don
Oct 20, 2010
Walter Bright
October 18, 2010
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: -------
October 18, 2010
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: -------
October 19, 2010
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: -------
October 20, 2010
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: -------