digitalmars.D.bugs - [Issue 8899] New: Erroneous delegate usage and map template
- d-bugmail puremagic.com (123/123) Oct 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8899
- d-bugmail puremagic.com (6/6) Nov 02 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8899
- d-bugmail puremagic.com (6/6) Nov 10 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8899
http://d.puremagic.com/issues/show_bug.cgi?id=8899 Summary: Erroneous delegate usage and map template Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: maxim maxim-fomin.ru --- Comment #0 from Maxim Fomin <maxim maxim-fomin.ru> 2012-10-26 13:44:49 PDT --- Currently dmd incorrectly treats delegates declared when type of parameter is omitted: ------------------------ import std.stdio; void main() { auto x = 0; writeln(typeof(a=>x).stringof); writeln(typeof((int a)=>x).stringof); writeln(typeof(delegate (a) { return x; }).stringof); writeln(typeof(delegate (int a) { return x; }).stringof); } ------------------------- This is available at dpaste http://dpaste.dzfl.pl/738f7301 The way map template accepts function parameter allows to hide type mismatch (if a=>c is used in other contexts, dmd will complain about inability to deduct arguments of type void). Exploit example is below: -----main.d-------------- version (bug) { import std.string; } import test; void main() { testfun(); } -------test.d----------- import std.algorithm; import std.stdio; void testfun() { int c = 0; writeln([0].map!(a=>c)[0]); } ------------------------- Depending on whether bug version is set or not, the program may run correctly or not. The only significant difference in generated code is in lambda function. In correct version it takes local value from -30(%rdx), in the broken version from (%rdx). It may seem wired how importing standard module can change behavior. Fixing syntax to delegate(int a) {} or (int a) => helps. Probably the bug comes from how dmd arranges code generation. If main.d includes std.string (or other heavily templated module) it is forced to instantiate templates when it generates code for main module even if they are irrelevant. However, because main imports test, it instantiates map template and generates delegate before code of test function is generated. Relevant parts of compilation logs of runnable and buggy versions: ----buggy.txt----- import object import std.string //imported, forcing instantiation during main codegen ..... code main function D main function std.array.empty!(int).empty function std.array.popFront!(int[]).popFront function std.array.front!(int).front function test.testfun.MapResult!(__lambda2,int[]).MapResult.back function test.testfun.MapResult!(__lambda2,int[]).MapResult.popBack function test.testfun.MapResult!(__lambda2,int[]).MapResult.this function test.testfun.MapResult!(__lambda2,int[]).MapResult.empty function test.testfun.MapResult!(__lambda2,int[]).MapResult.popFront function test.testfun.MapResult!(__lambda2,int[]).MapResult.front function test.testfun.MapResult!(__lambda2,int[]).MapResult.opIndex function test.testfun.MapResult!(__lambda2,int[]).MapResult.length function test.testfun.MapResult!(__lambda2,int[]).MapResult.opSlice function test.testfun.MapResult!(__lambda2,int[]).MapResult.save .... function test.testfun.__lambda2!(int).__lambda2 // testfunc isn't yet generated .... code test function test.testfun function test.testfun.map!(__lambda2).map!(int[]).map ----runnable.txt------- code main function D main code test function test.testfun function std.array.empty!(int).empty function std.array.popFront!(int[]).popFront function std.array.front!(int).front function test.testfun.map!(__lambda2).map!(int[]).map function test.testfun.MapResult!(__lambda2,int[]).MapResult.back function test.testfun.MapResult!(__lambda2,int[]).MapResult.popBack function test.testfun.MapResult!(__lambda2,int[]).MapResult.this function test.testfun.MapResult!(__lambda2,int[]).MapResult.empty function test.testfun.MapResult!(__lambda2,int[]).MapResult.popFront function test.testfun.MapResult!(__lambda2,int[]).MapResult.front function test.testfun.MapResult!(__lambda2,int[]).MapResult.opIndex function test.testfun.MapResult!(__lambda2,int[]).MapResult.length function test.testfun.MapResult!(__lambda2,int[]).MapResult.opSlice function test.testfun.MapResult!(__lambda2,int[]).MapResult.save ..... function test.testfun.__lambda2!(int).__lambda2 ------------------------ So, probably the problem is in generating delegate before generating function which local variables are accessed by delegate. This issue summarizes information from following issues: - 8514 : delegate and map leads to segfault, importing standard module affects behavior - 8854 : as described above - 8832 : similar code which uses map and delegate has different and incorrect behavior - 5064 (???): program crashes when using map and delegate - 7978 : map, take and iota functions with delegates -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8899 --- Comment #1 from Maxim Fomin <maxim maxim-fomin.ru> 2012-11-02 05:04:41 PDT --- - issue 8934 shows same problem -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 02 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8899 --- Comment #2 from Maxim Fomin <maxim maxim-fomin.ru> 2012-11-10 11:56:00 PST --- Issue 8994 shows similar problem. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 10 2012