Bug 17836 – ICE with custom 'map' template

Status
RESOLVED
Resolution
WORKSFORME
Severity
major
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2017-09-17T22:04:00Z
Last change time
2020-03-21T03:56:33Z
Keywords
ice, ice-on-invalid-code
Assigned to
No Owner
Creator
elronnd

Comments

Comment #0 by elronnd — 2017-09-17T22:04:00Z
This code causes an ICE in dmd and gdc. Under LDC it compiles without errors and when run it does exactly as expected: void main() { import std.stdio; template mmap(alias fun) { void mmap(T...)(T list) { foreach (item; list) { fun(item); } } } void printstuffs(T...)(T args) { void printer(G)(G arg) { writeln(arg); } mmap!printer(args); } printstuffs("bla", 7, 9.0); }
Comment #1 by elronnd — 2017-09-17T22:07:18Z
Potentially relevant: dmd just segfaults, but gdc actually prints a message: test.d: In function ‘mmap’: test.d:7:8: internal compiler error: in get_frame_for_symbol, at d/d-codegen.cc:2208 fun(item); ^
Comment #2 by ibuclaw — 2017-09-17T22:47:35Z
The compiler is checking if the nested function 'printer' is reachable from the function 'mmap'. It's not, because 'printer' is nested inside 'printstuffs', as so is not reachable. This would fall under a category of functions that are called by alias ('fun' is an alias to the function to call, of which the actual function is unreachable from the scope of 'mmap'). The front-end should ideally have a way to notify the code generator of this somehow, to notify us that there's no need to check whether the call is legal.
Comment #3 by ibuclaw — 2017-09-18T16:16:52Z
(In reply to Iain Buclaw from comment #2) > > The front-end should ideally have a way to notify the code generator of this > somehow, to notify us that there's no need to check whether the call is > legal. You would, however, run into other problems if 'printer' actually modifies anything in the parent frame. void printstuffs(T...)(T args) { int count = 0; void printer(G)(G arg) { writeln(arg); count++; } mmap!printer(args); } In the above case, runtime would segfault. As we have no way of determining the context pointer IIUC. The current AST handed from the front-end may be broken in this regard.
Comment #4 by ibuclaw — 2017-09-19T20:30:48Z
Note to anyone looking. For function call to mmap(...). Given that: FuncDeclaration fd = void mmap(T...); fd.toParent2() == main(); fd.parent.isTemplateInstance() == template mmap(T...); fd.parent.isTemplateInstance().tinst == template printstuffs(T...); fd.parent.isTemplateInstance().tinst.toAlias() == void printstuffs(T...); This is how you track the 'this' pointer for mmap to the frame of printstuffs. Fix for gdc will happen soon. Someone will have to look at dmd.
Comment #5 by ibuclaw — 2017-09-19T20:36:45Z
(In reply to Iain Buclaw from comment #4) > > This is how you track the 'this' pointer for mmap to the frame of > printstuffs. > Also note that you can't trust toParent2() here, as it returns the function the template was declared in. Parent access should be done through toParent() to properly inspect whether a template comes from another template instance (declared in another context).
Comment #6 by b2.temp — 2019-07-05T13:48:59Z
The bug as an ICE is gone now. Open another issue if the compilation is supposed to succeed.