Bug 4328 – templated unittests fail to link when instantiated from other file if compiler order isn't correct

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2010-06-16T06:46:00Z
Last change time
2011-02-06T23:52:53Z
Assigned to
nobody
Creator
schveiguy

Comments

Comment #0 by schveiguy — 2010-06-16T06:46:44Z
testunittest.d: struct S(T) { unittest { assert(0); } } testunittestmain.d: import testunittest; void main() { S!int s; } When compiled this way: dmd -unittest testunittest.d testunittestmain.d The following error occurs: testunittest.o: In function `_D12testunittest8__T1STiZ1S11__unittest3FZv': testunittestmain.d:(.text._D12testunittest8__T1STiZ1S11__unittest3FZv+0x9): undefined reference to `_D12testunittest15__unittest_failFiZv' collect2: ld returned 1 exit status If I compile this way: dmd -unittest testunittestmain.d testunittest.d The compiler generally has no problem with order of files for linking, I would expect the same here.
Comment #1 by r.sagitario — 2010-08-27T08:15:20Z
even worse: the link fails if the template is in a library and the library is not compiled with unittests: import std.stdio; void main() { writef("\n"); } dmd -unittest test.d OPTLINK (R) for Win32 Release 8.00.2 Copyright (C) Digital Mars 1989-2009 All rights reserved. http://www.digitalmars.com/ctg/optlink.html test.obj(test) Error 42: Symbol Undefined _D3std6format15__unittest_failFiZv --- errorlevel 1 Strangely, the relased phobos.lib is compiled with unittests, while the makefile does not pass "-unittest". So this does only show up when I compile the runtime library myself.
Comment #2 by r.sagitario — 2010-08-27T08:39:32Z
Here's a workaround: similar to the assert handling, generate the unittest_fail function whenever there is a template in the module: Index: template.c =================================================================== --- template.c (revision 632) +++ template.c (working copy) @@ -429,6 +429,13 @@ sc->module->toModuleAssert(); } + if (/*global.params.useUnitTests &&*/ sc->module) + { + // Generate this function as it may be used + // when template is instantiated in other modules + sc->module->toModuleUnittest(); + } + /* Remember Scope for later instantiations, but make * a copy since attributes can change. */
Comment #3 by bugzilla — 2011-02-06T23:52:53Z