Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Clang_cl precompiled headers causes missing symbols #40364

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR41394
Status NEW
Importance P enhancement
Reported by Allan Sandfeld Jensen (linux@carewolf.com)
Reported on 2019-04-05 07:35:36 -0700
Last modified on 2019-05-08 03:25:49 -0700
Version 8.0
Hardware PC Linux
CC erich.keane@intel.com, hans@chromium.org, llvm-bugs@lists.llvm.org, michael.p.rice@intel.com, neeilans@live.com, richard-llvm@metafoo.co.uk, rnk@google.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
With the latest clang_cl 8.0 we have tried reenabling using precompiled headers
for clang_cl on Windows with Qt.

Unfortunately it doesn't work and causes very long list of undefined symbols at
link time. All the missing symbols reported as referenced from PCH object file.
The symbols can be both from in and outside of the library, almost all inline
templated methods such as various forms of basic_string<T> methods.

There are several ways to work around the issue, most avoiding linking with PCH
object file:
1) Not linking in the pch object file and doing a debug build
2) Not linking in the pch object file and compiling all other files with
/Zc:dllexportInlines-
3) Not linking in the pch object file and compiling all other files with -
Xclang -building-pch-with-obj
4) Manually instantiating ALL templated classes possibly used by inline methods
(e.g. template class std::basic_string<char>). Note this is not necessary with
any other compiler.

They first three work-arounds all achieve the same goal of making the methods
generated in the PCH object file redundant, making linking with the buggy
object file unnecessary.

The issue simply appears to be that templated inline methods are partially
generated, but the template instantiations they need are not. Likely the
generated methods should been discarded unless used by another file in the
library.

In general it seems the far easiest to use a similar strategy as on non-windows
platform and let the normal object files generate the inline symbols they need,
even if that generates them more than necessary.

I have tried making a few simple cases, but the issue resists reproduction with
small examples and appears to require a larger library before it triggers.

Tell me if you need more information.
Quuxplusone commented 5 years ago
The errors at link time are stuff like:

lld-link: error: undefined symbol: "public: wchar_t & __cdecl
std::basic_string<wchar_t, struct std::char_traits<wchar_t>, class
std::allocator<wchar_t>>::front(void)"
(?front@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QEAAAEA_WXZ)
>>> referenced by .pch\release\Qt5Core_pch.obj

You can see how we tried working around the issue in https://codereview.qt-
project.org/#/c/257991/

We also found that cl.exe was a lot more "magical" in finding the header in -FI
than clang-cl.exe (could handle -FIqt_pch.h when clang-cl required -
FI../corelib/global/qt_pch.h). But I really don't expect the compiler to find
headers in an unmentioned grand-nephew directory. No idea how cl.exe does that
(or if it fails silently)
Quuxplusone commented 5 years ago

I timed out trying to analyze this.

Quuxplusone commented 5 years ago

I think we need a better reproducer to make progress on this.

It sounds like Allan already tried to come up with a small example.

Is it possible to find a large example, but somehow package it up in a self contained way so we can look at it?