This is an archive of the discontinued LLVM Phabricator instance.

Workaround for MSVC 16.3.* pre-c++17 type trait linkage
AbandonedPublic

Authored by erichkeane on Nov 27 2019, 9:36 AM.

Details

Summary

MSVC's type_trait header for the 16.3.* release in pre-c++17 mode
exposes explicitly specialized constexpr variables for _Is_integral,
is_void_v, and _Is_floating_point as not-inline (since that isn't
available in pre-C++17). The result is duplicate-symbols in any
program that includes <type_traits> more than once.

This patch works around this issue by making fairly specific cases (in
the system header, in MSVC mode, and in pre-c++17 mode) be weak_odr
linkage rather than External linkage.

Diff Detail

Event Timeline

erichkeane created this revision.Nov 27 2019, 9:36 AM
rnk added a subscriber: thakis.Nov 27 2019, 10:41 AM

I thought we agreed to remove the workaround that we had for this and just declare that the old MSVC STL release was buggy and users should update:
https://bugs.llvm.org/show_bug.cgi?id=42027
It's a point release that preserves ABI compatibility, so there's less motivation for us to add a compat hack.

In general, we should seriously think about sunsetting some MS compat hacks that aren't needed for new SDK/STL versions to save on clang maintenance costs. The complexity they add is surprisingly expensive. For example, -fdelayed-template-parsing is a recurring source of compat issues in clang-tools-extra (see the commit logs), and I would like to revive D66394 to get it disabled by default soon. (+@thakis)

In D70791#1762081, @rnk wrote:

I thought we agreed to remove the workaround that we had for this and just declare that the old MSVC STL release was buggy and users should update:
https://bugs.llvm.org/show_bug.cgi?id=42027
It's a point release that preserves ABI compatibility, so there's less motivation for us to add a compat hack.

In general, we should seriously think about sunsetting some MS compat hacks that aren't needed for new SDK/STL versions to save on clang maintenance costs. The complexity they add is surprisingly expensive. For example, -fdelayed-template-parsing is a recurring source of compat issues in clang-tools-extra (see the commit logs), and I would like to revive D66394 to get it disabled by default soon. (+@thakis)

Ah! I KNEW I had seen this bug before. I searched the bug database for a while for it.

I agree with sunsetting MS compat hacks as well, though I think we would need to support at least the most recentish versions. My test team tells me that this failure isn't fixed until the (yet to be released) 16.4 version of the MSVC, so at the moment we don't compile the 'current' version without -std=c++17. I don't see why r363191 was reverted, though I believe that this is both a less intrusive change, and is heavily specialized to only deal with this one case so hopefully it would not get reverted for the same reason.

rnk added a comment.Nov 27 2019, 11:44 AM

My version of cl.exe claims to have version 19.23.28107 and my headers are in Tools/MSVC/14.23.28105/include, and I see that this is fixed in xtr1common. is_integral_v and the helpers are defined with implicit template instantiations. There are no fully specialized template definitions in that header. So, my hope is that this problem will go away as users run the VS updater. Although, for buildbots and users such as myself who rarely start the IDE, that may take longer than we'd like.

In D70791#1762155, @rnk wrote:

My version of cl.exe claims to have version 19.23.28107 and my headers are in Tools/MSVC/14.23.28105/include, and I see that this is fixed in xtr1common. is_integral_v and the helpers are defined with implicit template instantiations. There are no fully specialized template definitions in that header. So, my hope is that this problem will go away as users run the VS updater. Although, for buildbots and users such as myself who rarely start the IDE, that may take longer than we'd like.

Ah, I see! I have no idea what that version is unfortunately... 14.23 is just 16.3 I think, but no idea which of the _10_ sub releases that is (https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes). My tester claims to have a completely up to date version, but I'll have them check.

erichkeane abandoned this revision.Dec 3 2019, 2:02 PM

Microsoft recently released 16.4 and has ceased support for the 16.3 line, so it isn't really important to me anymore. I'd thought this was a 'hold our nose and do it' type fix, but I don't think that is justified any longer now that Microsoft doesn't even support it.

I would like to revive D66394 to get it disabled by default soon.

As I recently informed @thakis via email, our compiler documentation was incorrect (I've informed the doc team and they're going to publish a fixed article soon). MSVC's behavior defaults to Microsoft one-phase (delayed template lookup) as it always has, changes to Standard two-phase under /permissive-, and can be escape-hatched back to Microsoft one-phase with /permissive- /Zc:twoPhase-.