http://d.puremagic.com/issues/show_bug.cgi?id=8093

           Summary: Returning ref from delegate foreach gives bad address
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: rejects-valid, wrong-code
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nob...@puremagic.com
        ReportedBy: k.hara...@gmail.com


--- Comment #0 from Kenji Hara <k.hara...@gmail.com> 2012-05-14 00:39:46 PDT ---
Test case:

extern(C) int printf(const char*, ...);

enum fbody = q{
    static int g = 10;
    printf("&g = %p : %d\n", &g, g);
    static struct S {
        int opApply(scope int delegate(ref int) dg) { return dg(g); }
    }
    S s;
    foreach (ref e; s)
        return g;
    assert(0);
};

void main()
{
    version(RefOut) ref int foo() out(r) { printf("&r = %p : %d\n", &r, r); }
                                  body { mixin(fbody); }
    version(ValOut)     int foo() out(r) { printf("&r = %p : %d\n", &r, r); }
                                  body { mixin(fbody); }
    version(Ref)    ref int foo() body { mixin(fbody); }
    version(Val)        int foo() body { mixin(fbody); }

    static if (is(typeof(&foo())))
    {
        auto p = &foo(); printf(" p = %p : %d\n", p, *p);
    }
    else
    {
        auto n = foo(); printf("&n = %p : %d\n", &n, n);
    }
}

output with command lines:

C:\> dmd -version=RefOut -run test.d
test.d(24): Error: undefined identifier r
test.d(24): Error: undefined identifier r

C:\> dmd -version=Ref -run test.d
&g = 00262260 : 10
 p = 0012FEB4 : 1245000

C:\> dmd -version=ValOut -run test.d
test.d(25): Error: undefined identifier r
test.d(25): Error: undefined identifier r

C:\> dmd -version=Val -run test.d
&g = 00282260 : 10
&n = 0012FE68 : 10

C:\>

description:
With `-version=Ref`, foo returns incorrect address. I can't find what's wrong.

With `-version=RefOut` or `ValOut`, out contract raises weird errors.
below patch will fix the errors, but generated code outputs same weird result
as like `-version=Ref`.

@3846 ReturnStatement::semantic() in statement.c
            // Construct: return vresult;
            if (!fd->vresult)
            {   // Declare vresult
                Scope *sco = fd->scout ? fd->scout : scx;
-               VarDeclaration *v = new VarDeclaration(loc, tret, Id::result,
NULL);
+                if (!fd->outId)
+                    fd->outId = Id::result;
+                VarDeclaration *v = new VarDeclaration(loc, tret, fd->outId,
NULL);
                v->noscope = 1;
                v->storage_class |= STCresult;
                if (((TypeFunction *)fd->type)->isref)
                    v->storage_class |= STCref | STCforeach;

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

Reply via email to