Bug 4277 – delegate reference wrong scope var value

Status
RESOLVED
Resolution
INVALID
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
All
Creation time
2010-06-05T07:27:00Z
Last change time
2010-06-28T20:45:28Z
Assigned to
nobody
Creator
changlon

Comments

Comment #0 by changlon — 2010-06-05T07:27:33Z
------------------------------------------------------------------------------- extern(C) void printf(char*, ... ); interface MyCall{ void call(int); } class MyObject{ MyCall[] list; void add(MyCall _mycall){ list ~= _mycall ; } void call(int i){ foreach( c ; list) { c.call(i); } } } class MyTest { public void run(){ MyObject obj = new MyObject ; test3(obj); test2(obj); test1(obj); obj.call(3); } static void test1(char[] name = "test1\0" )(MyObject obj){ printf("out: `%s` = `%x` \n\0".ptr , name.ptr, cast(void*) obj ); obj.add( new class( delegate(int i){ printf("in: `%s` = `%x` \n\0".ptr , name.ptr, cast(void*) obj ); } ) MyCall{ void delegate(int) dg; this(void delegate(int) _dg){ this.dg = _dg; } void call(int i) { dg(i); } } ) ; } void test2(MyObject obj){ test1!("test2\0")(obj); } void test3(ref MyObject obj){ test1!("test3\0")(obj); } } void main(){ auto t = new MyTest; t.run; } ------------------------------------------------------------------------------- out: `test3` = `a42fe0` out: `test2` = `a42fe0` out: `test1` = `a42fe0` in: `test3` = `414204` in: `test2` = `414204` in: `test1` = `12fe88`
Comment #1 by changlon — 2010-06-12T17:18:03Z
this block dwt, and dmd 1.062 beta still failure. but dmd2 is work.
Comment #2 by changlon — 2010-06-27T21:18:05Z
I test this bug in linux and windows, dmd1.062 print wrong address in linux too. dmd 2.047 is work for windows and linux. I use obj2asm to compare the d1 and d2 object file, but i have no ideal where is wrong . http://gool.googlecode.com/files/bug4277.tar this package include the bug2177.d (for both dmd1 and dmd2), 1.asm (from dmd1 generate bug2177.o file) and 2.asm (from dmd2 generate bug2177.o file).
Comment #3 by changlon — 2010-06-27T21:19:19Z
(In reply to comment #2) > I test this bug in linux and windows, dmd1.062 print wrong address in linux > too. > > dmd 2.047 is work for windows and linux. > > > I use obj2asm to compare the d1 and d2 object file, but i have no ideal where > is wrong . > > > http://gool.googlecode.com/files/bug4277.tar > this package include the bug2177.d (for both dmd1 and dmd2), 1.asm (from dmd1 > generate bug2177.o file) and 2.asm (from dmd2 generate bug2177.o file). sorry , i mean bug4277.d
Comment #4 by changlon — 2010-06-28T19:21:57Z
the ldc output: ---------------------------- out: `test3` = `b761bfe0` out: `test2` = `b761bfe0` out: `test1` = `b761bfe0` in: `test3` = `b761cfe0` in: `test2` = `b761cfc0` in: `test1` = `b761cfb4` ---------------------------- the dmd2 output: ---------------------------- out: `test3` = `b7617fe0` out: `test2` = `b7617fe0` out: `test1` = `b7617fe0` in: `test3` = `b7617fe0` in: `test2` = `b7617fe0` in: `test1` = `b7617fe0` --------------------------- the dmd1 output: ---------------------------- out: `test3` = `a42fe0` out: `test2` = `a42fe0` out: `test1` = `a42fe0` in: `test3` = `414204` in: `test2` = `414204` in: `test1` = `12fe88` --------------------------- there should be a error in dmd1-front and dmd-backend.
Comment #5 by nfxjfg — 2010-06-28T19:36:04Z
Duh, how about a simpler testcase?
Comment #6 by changlon — 2010-06-28T20:04:19Z
this is simpler testcase: ----------------------------------------------------- version( D_Version2 ){ mixin("extern(C) void printf(const(char)*, ... ) ;"); }else{ extern(C) void printf(char*, ... ); } class MyTest { void delegate(int)[] list ; public void run(){ test3(this); test2(this); test1(this); foreach( dg; list) { dg(3); } } static void test1(string name = "test1\0" )(MyTest obj){ printf("out: `%s` = `%x` \n\0".ptr , name.ptr, cast(void*) obj ); void add(int i){ printf("in: `%s` = `%x` \n\0".ptr , name.ptr, cast(void*) obj ); } obj.list ~= &add; } void test2(MyTest obj){ test1!("test2\0")(obj); } void test3(ref MyTest obj){ test1!("test3\0")(obj); } } void main(){ auto t = new MyTest; t.run; } --------------------------------------------------------------------------- my os is ubuntu 10.4 i386, dmd1: out: `test3` = `b750eff0` out: `test2` = `b750eff0` out: `test1` = `b750eff0` in: `test3` = `8050844` in: `test2` = `8050860` in: `test1` = `bf89037c` dmd2: out: `test3` = `b7494fe0` out: `test2` = `b7494fe0` out: `test1` = `b7494fe0` in: `test3` = `b7494fe0` in: `test2` = `b7494fe0` in: `test1` = `b7494fe0` ldc: out: `test3` = `b7549ff0` out: `test2` = `b7549ff0` out: `test1` = `b7549ff0` in: `test3` = `3` in: `test2` = `3` in: `test1` = `bfaae088`
Comment #7 by nfxjfg — 2010-06-28T20:38:23Z
You're creating a delegate of a nested function, and then return it. This is not allowed in D1. It's like writing "int* foo() { int x; return x; }" and then expecting the returned value is valid. Returning delegates to nested functions is allowed in D2, though.
Comment #8 by changlon — 2010-06-28T20:45:28Z
IF I understood correct, the dwt.widgets.Listener design by Frank Benoit is danger in d1. the source is: ------------------------------------------ module dwt.widgets.Listener; import dwt.widgets.Event; import tango.core.Traits; import tango.core.Tuple; public interface Listener { void handleEvent (Event event); } /// Helper class for the dgListener template function private class _DgListenerT(Dg,T...) : Listener { alias ParameterTupleOf!(Dg) DgArgs; static assert( is(DgArgs == Tuple!(Event,T)), "Delegate args not correct: delegate args: ("~DgArgs.stringof~") vs. passed args: ("~Tuple!(Event,T).stringof~")" ); Dg dg; T t; private this( Dg dg, T t ){ this.dg = dg; static if( T.length > 0 ){ this.t = t; } } void handleEvent( Event e ){ dg(e,t); } } Listener dgListener( Dg, T... )( Dg dg, T args ){ return new _DgListenerT!( Dg, T )( dg, args ); }