Created attachment 27911 [details] preprocessed source [forwarded from http://bugs.debian.org/667341] seen when building the qmf testsuite with 4.7 or the trunk. g++ -m64 -Wl,-O1 -o build/tst_qmailthread tst_qmailthread.o -L/usr/lib/x86_64-linux-gnu -L../../src/libraries/qmfclient/build -lqmfclient -lQtTest -lQtCore -lpthread tst_qmailthread.o: In function `tst_qmailthread::test_threadKeys()': tst_qmailthread.cpp:(.text+0x559b): undefined reference to `void QMailThreadSortKey::deserialize<QDataStream>(QDataStream&)' collect2: error: ld returned 1 exit status make[3]: *** [build/tst_qmailthread] Error 1 make[3]: Leaving directory `/home/packages/tmp/qmf-1.0.7~2011w23.2/tests/tst_qmailthread' the symbol is emitted in qmailthreadsortkey1.cpp, when built with 4.6 (both with -O1 and -O2), and with 4.7 with -O1, but not with -O2. Same behavior for the trunk. $ g++ -c -O1 -Wall -W -fPIC -o qmailthreadsortkey1.o qmailthreadsortkey1.cpp $ objdump -C -t qmailthreadsortkey1.o |grep deserialize 0000000000000000 l d .text._ZN15MailSortKeyImplI18QMailThreadSortKeyE11deserializeI11QDataStreamEEvRT_ 0000000000000000 .text._ZN15MailSortKeyImplI18QMailThreadSortKeyE11deserializeI11QDataStreamEEvRT_ 0000000000000000 l d .text._ZN18QMailThreadSortKey11deserializeI11QDataStreamEEvRT_ 0000000000000000 .text._ZN18QMailThreadSortKey11deserializeI11QDataStreamEEvRT_ 0000000000000000 w F .text._ZN15MailSortKeyImplI18QMailThreadSortKeyE11deserializeI11QDataStreamEEvRT_ 00000000000000a1 void MailSortKeyImpl<QMailThreadSortKey>::deserialize<QDataStream>(QDataStream&) 0000000000000000 w F .text._ZN18QMailThreadSortKey11deserializeI11QDataStreamEEvRT_ 0000000000000048 void QMailThreadSortKey::deserialize<QDataStream>(QDataStream&) $ g++ -c -O2 -Wall -W -fPIC -o qmailthreadsortkey1.o qmailthreadsortkey1.cpp $ objdump -C -t qmailthreadsortkey1.o |grep deserialize $
I can confirm that the symbol is not emitted. I cannot confirm this is an error.
This happens because -O2 now includes -finline-small-functions, so the call to deserialize from operator>> is inlined. Since deserialize is an implicit instantiation, the compiler only emits it in places where it is needed, and it isn't needed in this translation unit because all uses have been inlined. G++ expects that the definition of a template will be available in all translation units that use it unless it is explicitly instantiated. You can use -O2 -fno-inline-small-functions to restore the older behavior.