Bug 8093 – Returning ref from delegate foreach gives bad address

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2012-05-14T00:39:00Z
Last change time
2012-11-09T07:38:17Z
Keywords
pull, rejects-valid, wrong-code
Assigned to
nobody
Creator
k.hara.pg

Comments

Comment #0 by k.hara.pg — 2012-05-14T00:39:46Z
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;
Comment #1 by clugdbug — 2012-05-21T04:00:49Z
Same as bug 6141?
Comment #2 by k.hara.pg — 2012-11-09T02:24:03Z
https://github.com/D-Programming-Language/dmd/pull/1273 (In reply to comment #1) > Same as bug 6141? Yes, fixing it is necessary.
Comment #3 by github-bugzilla — 2012-11-09T05:55:56Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/90855d75802ed3440f0fad2f02593e801932d180 fix Issue 8093 - Returning ref from delegate foreach gives bad address https://github.com/D-Programming-Language/dmd/commit/093cf548588b0e6bdea23e2bb05642a559d31f2d Merge pull request #1273 from 9rnsr/fix8093 Issue 8093 - Returning ref from delegate foreach gives bad address