Bug 1350 – delegate literal inside tuple; wrong values

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2007-07-20T11:50:00Z
Last change time
2014-02-15T13:13:34Z
Keywords
wrong-code
Assigned to
nobody
Creator
chris

Comments

Comment #0 by chris — 2007-07-20T11:50:26Z
Gives the wrong value for i and writefln prints out extra garbage. version=BROKEN output: foo (char[],int)CALLBACK int = 0 bar correct output, when version is not set to BROKEN: foo CALLBACK int = 333 bar Code: import std.stdarg, std.traits; void Goat(Callbacks ...)(TypeInfo[] arguments, void* argptr) { args_loop: foreach(argti; arguments) { version(BROKEN) { foreach(Cb; Callbacks) { alias ParameterTypeTuple!(Cb) CBArgTypes; if(typeid(CBArgTypes[0]) == argti) { Cb(va_arg!(CBArgTypes[0])(argptr)); } } } else { alias Callbacks[0] Cb; alias ParameterTypeTuple!(Cb) CBArgTypes; if(typeid(CBArgTypes[0]) == argti) { Cb(va_arg!(CBArgTypes[0])(argptr)); } } } } import std.stdio; void foo(...) { writefln("foo"); Goat!( (int i) { writefln("CALLBACK int = %s", i); } )(_arguments, _argptr); writefln("bar"); } void main() { foo(333); }
Comment #1 by clugdbug — 2010-04-26T00:57:58Z
Reduced test case shows it has nothing to do with static foreach. import std.stdarg; void Goat(Callbacks ...)(void* argptr) { auto Cb = Callbacks[0]; // fails // alias Callbacks[0] Cb; // works static if (is(typeof(Cb) P == delegate)) static if (is(P Q == function)) alias Q CBArgTypes; Cb(va_arg!(CBArgTypes[0])(argptr)); } void foo(...){ Goat!( (int i) { assert(i==333); } )(_argptr); } void main() { foo(333); }
Comment #2 by clugdbug — 2010-04-26T01:55:37Z
Even further reduced. Nothing to do with varargs. ------------- void Goat(Callbacks ...)() { alias Callbacks[0] Cb; Callbacks[0](333); // fails // Cb(333); // but this works } void main() { Goat!( (int i) { assert(i==333); } )(); }
Comment #3 by clugdbug — 2010-07-16T10:20:02Z
*** Issue 4359 has been marked as a duplicate of this issue. ***
Comment #4 by clugdbug — 2010-07-16T10:20:42Z
*** Issue 4246 has been marked as a duplicate of this issue. ***
Comment #5 by clugdbug — 2010-07-22T02:26:16Z
This is happening because the delegate literal is passed as an alias template parameter. This parameter never gets resolved properly. In the example below, the compiler thinks that the parent of the delegate literal is 'Goat', whereas the true parent is 'main'. The problem might be in TupleExp::semantic(): if an element of the tuple is a symbol, maybe it should be attempting to resolve it. -------- void Goat(Callbacks ...)() { Callbacks[0](333); // fails } void main() { Goat!( (int i) { assert(i==333); } )(); }
Comment #6 by maxim — 2012-12-27T08:07:55Z
Fixed in issue 8774