Bug 9571 – link error due to using unique ids in anonymous funcliteral

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-02-22T10:15:00Z
Last change time
2013-09-19T09:50:58Z
Keywords
link-failure, pull
Assigned to
nobody
Creator
deadalnix

Comments

Comment #0 by deadalnix — 2013-02-22T10:15:07Z
a.d : import std.array; void main() { import b; foo(new A); } b.d : module b; class C { } class A { C[] cs; } import std.algorithm; auto foo(A a) { auto b = new B; a.cs.map!((C c){ return b.visit(c); }); } class B { C visit(C c) { return c; } } compilation : dmd -op -odobj/a -c src/a.d -m64 dmd -op -odobj/b -c src/b.d -m64 dmd -ofbin/sdc `find obj/a obj/b -type f | grep '\.o$'` -m64 Error : obj/a/src/a.o: In function `_D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult4backMFNdZC1b1C': src/a.d:(.text._D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult4backMFNdZC1b1C+0x64): undefined reference to `_D1b3fooFC1b1AZv12__lambda1196MFC1b1CZC1b1C' obj/a/src/a.o: In function `_D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult5frontMFNdZC1b1C': src/a.d:(.text._D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult5frontMFNdZC1b1C+0x64): undefined reference to `_D1b3fooFC1b1AZv12__lambda1196MFC1b1CZC1b1C' obj/a/src/a.o: In function `_D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult7opIndexMFmZC1b1C': src/a.d:(.text._D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1196MFC1b1CZC1b1CTAC1b1CZ9MapResult7opIndexMFmZC1b1C+0x77): undefined reference to `_D1b3fooFC1b1AZv12__lambda1196MFC1b1CZC1b1C'
Comment #1 by dlang-bugzilla — 2013-03-10T08:16:46Z
I'm seeing a similar error with Win64: a.obj : error LNK2019: unresolved external symbol _D1b3fooFC1b1AZv12__lambda1404MFC1b1CZC1b1C referenced in function _D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1404MFC1b1CZC1b1CTAC1b1CZ9MapResult4backMFNdZC1b1C a.exe : fatal error LNK1120: 1 unresolved externals --- errorlevel 1120 Links fine on Win32, though. Mr. deadalnix, does it happen without -m64? If not, please indicate the correct platform, since it is currently set to "All".
Comment #2 by deadalnix — 2013-03-10T08:23:54Z
(In reply to comment #1) > I'm seeing a similar error with Win64: > > a.obj : error LNK2019: unresolved external symbol > _D1b3fooFC1b1AZv12__lambda1404MFC1b1CZC1b1C referenced in function > _D1b3fooFC1b1AZv59__T9MapResultS35_D1b3foo12__lambda1404MFC1b1CZC1b1CTAC1b1CZ9MapResult4backMFNdZC1b1C > a.exe : fatal error LNK1120: 1 unresolved externals > --- errorlevel 1120 > > Links fine on Win32, though. > > Mr. deadalnix, does it happen without -m64? If not, please indicate the correct > platform, since it is currently set to "All". Mr. CyberShadow, I confirm the bug on 32bits as well.
Comment #3 by public — 2013-04-02T06:13:13Z
Want to note that it works if "auto foo" is changed to "void foo", so that it may be also somehow related to templates, exact conditions are weird though.
Comment #4 by public — 2013-04-10T07:31:40Z
Comment #5 by code — 2013-04-10T08:47:28Z
Could you please try to reduce the test case.
Comment #6 by public — 2013-04-10T09:30:15Z
I was not able to reduce it any further than moving A variable from parameter to foo itself, leaving foo signature as void foo(). Almost any change in b module resulted in lambda marked as a weak symbol and compilation succeeding. I have not tried to track this down really hard though as my pull solves more fundamental issue - that symbol should even be there at all, as well as several hundred phobos symbols. Still need to track down and fix special cases found by test suite though. Working on it right now.
Comment #7 by code — 2013-04-10T17:57:16Z
cat > a.d << CODE import b; void main() { foo(); } CODE cat > b.d << CODE struct MapResult(alias fun) { void bar() { fun(0); } } auto foo() { version (all) { alias MapResult!(function(int c) => 0) M; } else { // works because it uses a named function literal auto func = function(int c) => 0; alias MapResult!(func) M; } } CODE dmd -c a dmd -c b dmd a.o b.o -------- During the compilation of a.d semantic3 is run on auto foo() and thus an instantiation of MapResult!(...) is added to a.o. The problem is that the anonymous funcliteral in a.o and the one in b.o used a different unique id suffix. Because semantic3 on MapResult.bar() is not run during a's compilation the funcliteral is never referenced and missing from a.o. nm a.o | grep funcliteral U _D1b3fooFZv14__funcliteral5FNaNbNfiZi nm b.o | grep funcliteral T _D1b3fooFZv14__funcliteral1FNaNbNfiZi
Comment #8 by code — 2013-04-10T18:19:57Z
(In reply to comment #7) > Because semantic3 on MapResult.bar() is not run during a's compilation the > funcliteral is never referenced and missing from a.o. > That was incorrect semantic3 for the function literal and MapResult.bar is run and bar is added as a weak symbol to a.o which actually causes the link error because the funcliteral remains undefined. We need to fix the unique id issue for anonymous literals. We shouldn't emit an unused template instance to a.o just because we ran semantic3 on foo, note that foo returns void.
Comment #9 by public — 2013-04-11T00:32:09Z
Thanks for tracking down the root cause for this specific issue. I'll move my pull request to its own issue then.
Comment #10 by public — 2013-09-13T07:50:45Z
The root cause of this issues got hidden / fixed by https://github.com/D-Programming-Language/dmd/pull/2550 (as only one template instance is emitted and thus only one literal ID gets generated). I can't imagine any other way to manifest this issue (without using template instances) but it may be theoretically possible.
Comment #11 by k.hara.pg — 2013-09-17T01:26:10Z
(In reply to comment #10) > The root cause of this issues got hidden / fixed by > https://github.com/D-Programming-Language/dmd/pull/2550 (as only one template > instance is emitted and thus only one literal ID gets generated). > > I can't imagine any other way to manifest this issue (without using template > instances) but it may be theoretically possible. Able to cause the issue by combining -inline. //a.d import b; void main() { foo(); } // b.d struct MapResult(alias fun) { void bar() { fun(0); } } auto foo() { alias MapResult!(function(int c) => 0) M; M m; m.bar(); } Command: $ dmd -inline -c a.d $ dmd -inline -c b.d $ dmd -oftest.exe a.obj b.obj OPTLINK (R) for Win32 Release 8.00.12 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html a.obj(a) Error 42: Symbol Undefined _D1b51__T9MapResultS34_D1b3foo14__funcliteral4FNaNbNfiZiZ9MapResult3barMFNaNbNfZv --- errorlevel 1
Comment #12 by k.hara.pg — 2013-09-17T01:29:05Z
Comment #13 by github-bugzilla — 2013-09-17T02:51:20Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/225188755132e42ae97ca398be7d7f3af2b5a1e2 fix Issue 9571 - link error due to using unique ids in anonymous funcliteral https://github.com/D-Programming-Language/dmd/commit/3395a17dfe506c7a0dcf7370e7e4de4d98391528 Merge pull request #2566 from 9rnsr/fix9571 Issue 9571 - link error due to using unique ids in anonymous funcliteral
Comment #14 by deadalnix — 2013-09-19T09:50:58Z
(In reply to comment #12) > https://github.com/D-Programming-Language/dmd/pull/2566 Dude, I'm not in Japan for so long, but if you have one moment on Tokyo next week, I'd buy you a beer (or whatever you prefer).